2015-01-09 13 views
5

ho cronometrato una sezione di codice Python su Ubuntu utilizzando time.clock e time.time:Perché time.clock fornisce un tempo trascorso più lungo di time.time?

clock elapsed time: 8.770 s 
time elapsed time: 1.869 s 

Capisco che time.time utilizza l'ora di sistema e time.clock utilizza il clock del processore. Ha senso per me quando time.time dà un tempo trascorso più lungo di time.clock: il processore non era attivo per tutto il tempo (ad esempio una chiamata a time.sleep).

Ma perché/quando l'orologio del processore fornisce un tempo trascorso tanto superiore a rispetto all'ora di sistema?


addendum

ho fatto un test ruvida calcolando la stessa funzione con una mappa standard, con una mappa pool di processi, e una mappa pool di thread. Comprensibilmente, il pool di processi è più veloce e il pool di thread è più lento. Più interessante: la temporizzazione dell'orologio è in meno rispetto alla temporizzazione con il pool di processori ma maggiore nel pool di thread.

Ancora una volta, capisco perché la temporizzazione dell'orologio è inferiore al pool di processori: presumibilmente il processo master non fa molto e aspetta solo che i processi del pool si completino. Ma perché l'orologio cronometra di più con il pool di thread? Qualche intuizione?

Risultati:

map 
    time 1738.8 
    clock 1739.6 
mp pool 
    time 580.1 
    clock 15.9 
thread pool 
    time 3455.3 
    clock 5378.9 

Codice:

from time import clock, sleep, time 
from multiprocessing.pool import ThreadPool 
from multiprocessing import Pool 
import random 

def f(i): 
    x = [random.random() for j in range(100000)] 
    return x[i] 

def t(fn): 
    t0, c0 = time(), clock() 
    for i in range(10): fn(f,range(16)) 
    print ' time ', round(1000*(time()-t0),1) 
    print ' clock', round(1000*(clock()-c0),1) 

if __name__ == '__main__': 
    print 'map' 
    t(map) 

    pool = Pool(8) 
    print 'mp pool' 
    t(pool.map) 

    pool = ThreadPool(8) 
    print 'thread pool' 
    t(pool.map) 
+0

Qualcosa di parallelo? Stai usando 8 core? – dmg

+0

Sì, anche questo è il mio sospetto. Quindi l'orologio fornisce un tempo di clock trascorso per tutti i processori? – jmilloy

+0

Potrebbe essere specifico per il sistema operativo, ma ho visto problemi simili con molti strumenti di temporizzazione/librerie – dmg

risposta

2

tempo di CPU può superare il tempo muro se si esegue su più CPU. Non l'ho visto in Python, ma l'ho visto sicuramente usando la funzione clock con più thread da C, e presumibilmente il codice Python chiama direttamente questa funzione C.

Riguardo al "perché": ci stai pensando nel modo sbagliato. L'importante è che quanti core eseguono il tuo programma. Se un core gira per un secondo nel corso di due secondi di tempo a muro che ha senso per te, ma cosa succede se quattro core eseguono ciascuno per un secondo sullo stesso intervallo di tempo. Quindi hai 4 secondi di tempo CPU in 2 secondi di tempo di parete. Gli account del kernel per il tempo della CPU misurano tutti i core. Se più core vengono eseguiti durante lo stesso secondo, hai trascorso più CPU secondi durante quel secondo. Questa è la misurazione dei costi che interessa lo scheduler e presumibilmente è la metrica su cui è costruito clock. Questo potrebbe non essere il parametro che ti interessa, ma è così che funziona.

+0

Empiricamente, sembra essere il caso. Perché? – jmilloy

+0

La documentazione di ['std :: clock'] (http://en.cppreference.com/w/cpp/chrono/c/clock) dichiara semplicemente questo fatto. – b4hand

+0

Sto cercando di scoprire perché. Qual è l'orologio del processore che misura? Sembra misurare la quantità di tempo in cui il processore è attivo, ma ciò non può essere completamente accurato perché il processore non può essere attivo per più tempo di quello che è effettivamente passato (o può, a causa del modo in cui il multi-threading funziona livello hardware?) La risposta che hai fornito conferma la mia esperienza e sottolinea che è documentata (cioè non un bug). Ma non spiega perché. – jmilloy