2015-06-06 8 views
27
time javac Main.java          --> 0m1.050s 
time javac Main.java & javac Main.java     --> 0m1.808s 
time javac Main.java & javac Main.java & javac Main.java --> 0m2.690s 
time javac Main.java & ... 8 time       --> 0m8.309s 

Quando eseguiamo javac comando in parallelo e con ogni aumento javac comando ~1 sec viene aggiunto per tutto il comando javac per completare.esecuzione perché parallelo su java compilazione rimessa crescita lineare nel tempo

Perché c'è una crescita lineare è il tempo?

È tutto javac processo durante l'esecuzione coinvolti in una sorta sul locks, se sì, come superarla in modo da non avere una crescita lineare nel tempo


PS: Ho cercato in precedenza su single core machine, double core machine, 4 core machine tutti hanno mostrato lo stesso comportamento.

PS2: ambiente RedHat7, javac 1.7.0_79

+2

Potrebbe facilmente essere legato all'I/O, non alla CPU. –

+1

qualsiasi idea su come confermare se il suo io legato ... sembra così dato che i nostri dati sono molto piccoli – Bhuvan

+0

Hmmm, 'javac' vuole i file. Immagino che potresti usare un disco RAM. Mi sarei anche assicurato che 'Main.java' fosse ** grande **, quindi stai veramente controllando la compilazione e carica/salva. Ma ovviamente la vera domanda è: cosa stai cercando di ottimizzare? Perché se è l'intero processo, I/O è un fattore importante che non vorrete testare. –

risposta

27

il compilatore Java gestisce già dividendo il suo lavoro tra i processori disponibili, anche se solo la compilazione di un singolo file. Pertanto, l'esecuzione separata di istanze del compilatore in parallelo non produrrà i guadagni in termini di prestazioni che ci si aspetta.

Per dimostrarlo, ho generato un grande programma java (1 milione di linee, 10.000 metodi) in un singolo file chiamato Main1.java. Quindi ha effettuato copie aggiuntive come Main2.java tramite Main8.java. Compilazione volte sono i seguenti:

singolo compilazione del file:

time javac Main1.java & --> (real) 11.6 sec 

Guardando questo singolo file viene compilato in top utilizzo del processore rivelato prevalentemente nell'intervallo 200-400% (che indica l'utilizzo CPU multiple, 100% per CPU) , con picchi occasionali nell'intervallo del 700% (il massimo su questa macchina è dell'800% poiché ci sono 8 processori).

Avanti, due file contemporaneamente:

time javac Main1.java & --> (real) 14.5 sec 
time javac Main2.java & --> (real) 14.8 sec 

Così ci sono voluti solo 14,8 secondi per compilare due, quando ha preso 11,6 secondi per compilare uno. Questo è decisamente non lineare. Era chiaro guardando a top mentre questi erano in esecuzione che ancora una volta ogni compilatore Java stava sfruttando al massimo quattro CPU contemporaneamente (con picchi occasionali più alti). Per questo motivo, i due compilatori hanno funzionato su otto CPU per lo più in parallelo l'una con l'altra.

Avanti, quattro file contemporaneamente:

time javac Main1.java & --> (real) 24.2 sec 
time javac Main2.java & --> (real) 24.6 sec 
time javac Main3.java & --> (real) 25.0 sec 
time javac Main4.java & --> (real) 25.0 sec 

Va bene, qui abbiamo colpito il muro. Non possiamo più parallelizzare il compilatore. Quattro file hanno impiegato 25 secondi quando due hanno richiesto 14.8. C'è un po 'di ottimizzazione lì, ma è principalmente un aumento di tempo lineare.

Infine, otto simultaneamente:

time javac Main1.java & --> (real) 51.9 sec 
time javac Main2.java & --> (real) 52.3 sec 
time javac Main3.java & --> (real) 52.5 sec 
time javac Main4.java & --> (real) 53.0 sec 
time javac Main5.java & --> (real) 53.4 sec 
time javac Main6.java & --> (real) 53.5 sec 
time javac Main7.java & --> (real) 53.6 sec 
time javac Main8.java & --> (real) 54.6 sec 

questo era in realtà un po 'peggio che lineare, come otto ha preso 54,6 secondi, mentre quattro sono voluti solo 25,0.

Quindi penso che il take-away di tutto questo sia avere fiducia che il compilatore farà un lavoro decente cercando di ottimizzare il lavoro che gli dai attraverso le risorse della CPU disponibili, e che il tentativo di aggiungere ulteriore parallelizzazione a mano avrà un limitato (se del caso) beneficio.

Edit:

Per riferimento, ci sono due voci che ho trovato nel database dei bug di Oracle per quanto riguarda migliorare javac per sfruttare più processori:

  • Bug ID: JDK-6629150 - La denuncia originaria, questo è stato eventualmente contrassegnato come duplicato di:
  • Bug ID: JDK-6713663 - Suggerisce la risoluzione e in base alla "Data risolta" sembra che il supporto multiprocessore in javac sia stato aggiunto il 2008-06-12.
+1

bella spiegazione, ma se prendiamo 8 ciao mondo java (come opposto al tuo) file compilare poi in parallelo usando 8 javac su una macchina a 8 core, quindi dovrebbe essere completato in 1 sec .... giusto? – Bhuvan

+0

@ user2410148: utilizzando un piccolo file "Hello world" ho ottenuto i seguenti tempi di compilazione: 1 ha impiegato 0,32 secondi; 2 impiegarono 0,39 secondi; 4 impiegarono 0,54 secondi; 8 ha impiegato 1,02 secondi. Sembra seguire lo stesso schema, dove suddividerlo in due compila in parallelo, ma poi provare a fare quattro o otto è stato un aumento più lineare nel tempo. Penso che lo stesso concetto si applichi anche su piccola scala: lascia che il compilatore faccia la parallelizzazione per te. –

+0

Non credo che la tua conclusione sia valida. Per dimostrare il tuo punto non dovresti stabilire il tempo necessario per compilare 1-8 in serie? Altrimenti si stanno confrontando due diverse quantità di lavoro. Dalla mia stima dei tuoi numeri posso dare il via a javac e aspettare 88 secondi o posso parallelizzarlo dalla riga di comando e aspettare 55 secondi. La maggior parte dei miei file java si trova nell'intervallo di 500 linee, immagino che javac avrà più difficoltà a utilizzare più core in file/classi più piccoli. Non sto dicendo che il javac parallelo 16000 sia la soluzione ideale, ma non sono d'accordo con il consiglio di avere solo fede. – Ryan

Problemi correlati