2012-01-25 21 views
38

Diciamo che volevo confrontare due programmi: foo.py e bar.py.Il comando `time` UNIX è sufficientemente accurato per i benchmark?

sono un paio di migliaia di piste e le rispettive medie di time python foo.py e time python bar.py abbastanza adeguata per il profiling e confrontando la loro velocità?


Edit: Inoltre, se l'esecuzione di ogni programma è stato inferiore al secondo (per scontato che non fosse per il precedente), sarebbe time essere ancora bene da usare?

+0

Quanto dura il runtime di una singola esecuzione? Se è inferiore a un secondo, probabilmente avrai errori sistematici a causa della scarsa precisione e gli errori sistematici non verranno eliminati facendo una media. –

+1

In generale, il codice che vorrei profilare in primo luogo avrebbe tempi di esecuzione molto più lunghi di un secondo. – chrisdotcode

+0

Inoltre, anche se il codice intensivo avesse tempi di esecuzione inferiori al secondo, l'esecuzione di tale operazione un milione di volte * all'interno * del programma attenuerebbe gli errori sistematici? In questo modo, "tempo" sarebbe confrontato con un milione di giri di pippo con un milione di giri di barre. – chrisdotcode

risposta

49

time produce tempi sufficienti per i benchmark che durano più di un secondo, altrimenti il ​​tempo impiegato da exec() in un processo può essere grande rispetto al suo tempo di esecuzione.

Tuttavia, quando si esegue il benchmarking è necessario prestare attenzione al cambio di contesto. Cioè, un altro processo potrebbe utilizzare CPU, contendendo così la CPU con il benchmark e aumentando il tempo di esecuzione. Per evitare conflitti con altri processi è necessario eseguire un punto di riferimento come questo:

sudo chrt -f 99 /usr/bin/time --verbose <benchmark> 

sudo chrt -f 99 corre il vostro punto di riferimento nella FIFO di classe in tempo reale con la priorità 99, che rende il processo il processo di priorità assoluta ed evita cambio di contesto (è possibile cambia il tuo /etc/security/limits.conf in modo che non richieda un processo privilegiato per utilizzare le priorità in tempo reale).

Inoltre, rende time tutte le statistiche disponibili, compreso il numero di scambi di contesto in cui è stato eseguito il benchmark, che normalmente dovrebbe essere pari a 0, altrimenti si potrebbe desiderare di rieseguire il benchmark.

Ed è meglio disabilitare il CPU frequency scaling e aumentare, in modo che la frequenza della CPU rimane costante durante il punto di riferimento per ottenere risultati coerenti.

+0

Questa è la risposta più completa, ma per quanto riguarda i casi in cui il tempo di esecuzione del programma è inferiore a un secondo? – chrisdotcode

+0

Grazie Chris. Se impiega meno di un secondo una gran parte di quel tempo può essere 'exec()' ing il processo. È meglio fare un benchmark in pochi secondi per minimizzare il bias del tempo di avvio. –

3

Sì. Il comando time fornisce sia il tempo trascorso sia la CPU consumata. Quest'ultimo è probabilmente quello su cui dovresti concentrarti, a meno che non stai facendo un sacco di I/O. Se il tempo trascorso è importante, assicurarsi che il sistema non abbia altre attività significative durante l'esecuzione del test.

5

Sì, time è sufficientemente preciso. E dovrai eseguire solo una dozzina di volte i tuoi programmi (a patto che la corsa duri più di un secondo o una frazione significativa di un secondo, ovvero almeno 200 millisecondi). Naturalmente, il file system sarebbe caldo (cioè i file piccoli sarebbero già stati memorizzati nella RAM) per la maggior parte delle esecuzioni (tranne il primo), quindi tenetelo in considerazione.

la ragione per cui si desidera avere il time -d eseguito per durare alcuni decimi di secondo è l'accuratezza e la granularità della misurazione del tempo. Non aspettarti meno di un centesimo di secondo di precisione. (Avete bisogno di qualche speciale opzione del kernel di averlo un millisecondo)

Dall'interno dell'applicazione, è possibile utilizzare clock, clock_gettime, gettimeofday, getrusage, times (che sicuramente hanno un Python equivalente).

Non dimenticare di leggere la pagina man time(7).

+0

Che cos'è l'ora -d'? Non vedo quell'argomento nella pagina man in linux o OSX. – dfc

+0

Intendevo l'aggettivo * cronometrato *, con riferimento al comando 'time' –

31

Al giorno d'oggi, IMO, non v'è alcuna ragione per usare time a fini di benchmarking. Utilizzare invece perf stat.Ti dà molte più informazioni utili e può ripetere il processo di benchmarking ogni dato numero di volte e fare statistiche sui risultati, cioè calcolare la varianza e il valore medio. Questo è molto più affidabile e altrettanto semplice da usare come time:

perf stat -r 10 -d <your app and arguments> 

Il -r 10 verrà eseguito la vostra applicazione per 10 volte e fare statistiche su di esso. -d emette alcuni più dati, ad esempio errori di cache.

Così mentre time potrebbe essere abbastanza affidabile per le applicazioni di lunga durata, sicuramente non è affidabile quanto perf stat. Usalo invece.

Addendum: Se davvero si vuole continuare a utilizzare time, almeno non utilizzare il comando bash-incorporato, ma il vero affare-in modalità dettagliata:

/usr/bin/time -v <some command with arguments> 

L'uscita è quindi, per esempio :

Command being timed: "ls" 
    User time (seconds): 0.00 
    System time (seconds): 0.00 
    Percent of CPU this job got: 0% 
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 
    Average shared text size (kbytes): 0 
    Average unshared data size (kbytes): 0 
    Average stack size (kbytes): 0 
    Average total size (kbytes): 0 
    Maximum resident set size (kbytes): 1968 
    Average resident set size (kbytes): 0 
    Major (requiring I/O) page faults: 0 
    Minor (reclaiming a frame) page faults: 93 
    Voluntary context switches: 1 
    Involuntary context switches: 2 
    Swaps: 0 
    File system inputs: 8 
    File system outputs: 0 
    Socket messages sent: 0 
    Socket messages received: 0 
    Signals delivered: 0 
    Page size (bytes): 4096 
    Exit status: 0 

Soprattutto notare come questo sia in grado di misurare l'RSS di picco, che è abbastanza spesso, se si desidera confrontare l'effetto di un cerotto sul consumo di memoria di picco. Cioè usa quel valore per confrontare prima/dopo e se c'è una diminuzione significativa nel picco RSS, allora hai fatto qualcosa di giusto.

+2

Su Debian avrete bisogno del pacchetto 'linux-tools- $ version'. – wieczorek1990

+0

Su Ubuntu installa 'linux-tools-generic' (tramite [questa domanda] (https://askubuntu.com/questions/50145/how-to-install-perf-monitoring-tool)) – Kariem

Problemi correlati