2009-07-19 6 views
8

Ho trovato un buon question per la misurazione delle prestazioni funzione e le risposte consiglia di utilizzare cronometro come segueBest Practice for Cronometro in macchina multi processori?

Stopwatch sw = new Stopwatch(); 
sw.Start(); 
//DoWork 
sw.Stop(); 
//take sw.Elapsed 

Ma è valida se si esegue in più macchina processori? il thread può essere passato a un altro processore, vero? Anche la stessa cosa dovrebbe essere in Enviroment.TickCount. Se la risposta è sì devo avvolgere il mio codice all'interno BeginThreadAffinity come segue

Thread.BeginThreadAffinity(); 
Stopwatch sw = new Stopwatch(); 
sw.Start(); 
//DoWork 
sw.Stop(); 
//take sw.Elapsed 
Thread.EndThreadAffinity(); 

PS

La commutazione può avvenire attraverso il livello filo non solo il livello di processore, per esempio se la funzione è in esecuzione in un altro thread in modo che il sistema possa passare a un altro processore, se ciò accade, il cronometro sarà valido dopo questa commutazione?

non sto usando cronometro per misurare perfromance solo ma anche per simulare funzione timer utilizzando Thread.Sleep (per evitare sovrapposizioni call)

risposta

5

Se la funzione stessa non è multithread (ad esempio non riprodursi altri thread/processi e attendere che vengano completati), l'unico problema è la tua macchina.

Se la macchina è impegnata a svolgere altre attività, potrebbe invalidare il test (ad esempio codificare un video H.264 mentre si esegue un test associato alla CPU). Allo stesso modo, se si utilizza tutta la memoria fisica per testare qualcosa che è legato alla memoria, allora potrebbe invalidare i risultati.

Pertanto, il principio generale è che la macchina deve essere sottoposta a un carico da minimo a normale durante lo svolgimento di tali test. Oltre a questo non c'è un problema di multiprocessing. Sì, il programma potrebbe scambiare core mentre è in esecuzione, ma l'overhead di farlo è una piccola percentuale del tempo misurato o il tempo misurato è così piccolo che la granularità della misurazione del tempo del sistema è un problema.

+0

se la funzione è in esecuzione in un thread in background, questo significa che il thread della funzione può passare a un altro processore che porta all'errore nelle misurazioni –

+0

Secondo MSDN: "I thread in background sono identici ai thread in primo piano, eccetto che i thread in background non impedire che un processo termini ". Rif: http: // msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx –

+0

@Tormod Fjeldskår, i thread in primo piano/sfondo possono essere passati ad altri processori quindi non mi interessa il suo tipo ma l'ho menzionato nel mio commento per esempio non di più –

2

Penso che tu stia chiedendo dell'implementazione a basso livello di Cronometro e se il passaggio dei processori nel mezzo dell'esecuzione potrebbe invalidare il comportamento. L'implementazione fa uso QueryPerformanceCounter internamente (vedere le BCL Fonti di riferimento MS; ho confermato in .NET 4.0, almeno.)

Il MS documentation per questa API afferma:

su un computer multiprocessore, è non dovrebbe importare quale processore è chiamato . Tuttavia, è possibile ottenere risultati diversi su processori diversi a causa di errori nel sistema di input/output di base (BIOS) o nel livello di astrazione dell'hardware (HAL).

Quindi, sei corretto; in linea di principio, non dovrebbe avere importanza, ma questo commento suggerisce che sono stati osservati casi in cui l'implementazione non è conforme all'interfaccia prevista. Se si desidera garantire la correttezza della misurazione, è possibile utilizzare l'affinità della filettatura, come indicato. Detto questo, suppongo che gli errori osservati siano piuttosto piccoli, poiché una grande differenza sarebbe un BIOS piuttosto grave o un bug HAL.