2012-11-17 4 views
6

Durante la scrittura di microbenchmarks, è possibile osservare una grande differenza in fase di esecuzione a seconda che un metodo sia stato compilato o meno. C'è un modo per capire da un programma se un particolare metodo è stato compilato? In alternativa, c'è un modo per richiederlo o sapere come riscaldarlo adeguatamente senza ulteriori informazioni su ad es. le bandiere passate alla JVM? Ovviamente questo non sarà necessariamente perfetto (ad esempio potrebbe esserci qualche condizione che fa sì che la JVM ricada al codice interpretato), ma sarebbe certamente un miglioramento.C'è un modo per dire dalla JVM se un particolare metodo è stato compilato con JIT?

+0

È possibile misurare empiricamente il tempo di esecuzione del metodo e controllare la distribuzione dei risultati. In genere si ha un salto quando viene compilato. C'era una domanda su SO su questa metodologia, ma non riesco a trovarla adesso. Ovviamente, questo è alquanto invadente. – assylias

+0

Sono quasi sicuro che la risposta sia "no, decisamente no". –

+0

@assylias - Funziona solo se sei sicuro che il metodo non sia già stato compilato. Altrimenti non c'è un salto da trovare. Inoltre, i solidi algoritmi di rilevamento del cambiamento sono un problema da codificare. –

risposta

3

Per Sun/Oracle JVM è possibile utilizzare l'impostazione -XX:CompileThreshold=1000.

Questo - come official documentation Uniti - definisce:

Numero di chiamate di metodi/rami prima di compilare

Poi, basta usare il numero a "riscaldare" la JVM.

È inoltre possibile utilizzare -XX:-PrintCompilation insieme a -XX:CompileThreshold per ricevere una notifica (nella console) quando viene compilato un metodo.

+0

* "senza ulteriori informazioni su, ad esempio, flag passati a JVM" * ... – assylias

+0

Che cos'è un "ramo", come conteggiato dalla JVM? –

+0

@RexKerr - La JVM tenta di stimare quanto tempo viene speso nel metodo (e quindi quanto vantaggio ci sarebbe per compilarlo), principalmente contando le voci e le diramazioni arretrate (che indicherebbero i loop). Ma potrebbero esserci altri fattori inclusi. –

1

Sono quasi sicuro che è possibile attivare la registrazione che mostrerà quando i metodi sono JITCed. Ma non so in alcun modo da dentro Java per dire.

E tenere presente che la compilazione JIT non è un evento ma un processo: un metodo può essere ricompilato più volte, man mano che maggiori informazioni sulle sue caratteristiche diventano disponibili.

Infine, si noti che il "riscaldamento" è incerto nel caso generale. Mentre di solito puoi "scaldare" un singolo metodo in modo affidabile, è molto più difficile anche con un'applicazione di dimensioni modeste, a causa di una serie di fattori.

(Anche se io non conosco alcuna ragione per cui la capacità di leggere una sorta di stato di JITC per un metodo non può essere aggiunta agli strumenti di debug incorporato.)

Aggiunto: Una cosa da stare attenti , quando il benchmarking del codice "snippet", è che il metodo più esterno che fa tutto il ciclo spesso non è compatibile con JITC (a seconda di come è implementato JITC) a causa del fatto che non ritorna mai e quindi la versione di JITCed non può mai essere chiamato. Quindi si dovrebbe sempre posizionare la "carne" del codice da sottoporre a benchmark in un metodo separato che viene chiamato ripetutamente, mettendo il ciclo e il codice da benchmark nello stesso metodo.

+0

Ho specificato "microbenchmark".Le applicazioni più grandi sono difficili da definire. –

+0

Infatti. Si dovrebbe anche essere a conoscenza della raccolta dei dati inutili, indipendentemente dal fatto che il test case abbia il livello previsto di invio multiplo per il codice reale, se i risultati vengano scartati e quindi il codice possa essere eliminato, ecc. Ecc. Anche i microbenchmark non sono semplici da ottenere correttamente ! –