Come punto di riferimento su processori multi-core
-
04-10-2019 - |
Domanda
Cerco modi per eseguire micro-benchmark su processori multi-core.
Contesto:
a circa lo stesso tempo processori desktop introdotte esecuzione fuori ordine che le prestazioni reso difficile da prevedere, che, istruzioni speciali, forse non a caso, ha introdotto anche per ottenere tempi molto precisi. Esempio di queste istruzioni sono rdtsc
su x86 e rftb
su PowerPC. Queste istruzioni hanno dato tempi che sono stati più precisi di quanto si possa essere consentito da una chiamata di sistema, i programmatori hanno permesso di micro-punto di riferimento a squarciagola, nel bene e nel male.
Su un processore ancora più moderno con più nuclei, alcuni dei quali possono ospitare qualche volta, i contatori non sono sincronizzati tra i core. Ci viene detto che rdtsc
non è più sicuro da usare per il benchmarking, ma deve essere stato sonnecchiare quando stavamo spiegato le soluzioni alternative.
Domanda:
Alcuni sistemi possono salvare e ripristinare il contatore di prestazioni e di fornire una chiamata API per leggere la somma corretta. Se si sa che cosa questo invito è per qualsiasi sistema operativo, fatecelo sapere in una risposta.
Alcuni sistemi può consentire di spegnere core, lasciando una sola esecuzione. So che Mac OS X Leopard fa quando il Preference Pane destra è installato dagli strumenti di sviluppatori. Pensi che questo sicuro fanno rdtsc
da usare di nuovo?
Più contesto:
Si prega di assumere So quello che sto facendo quando si cerca di fare un micro-benchmark. Se siete del parere che se i guadagni di un'ottimizzazione non possono essere misurati cronometrando l'intera applicazione, non vale la pena di ottimizzazione, sono d'accordo con te, ma
-
Non posso periodo l'intera applicazione fino alla struttura di dati alternativo è finito, che richiede molto tempo. Infatti, se il micro-punto di riferimento non sono stati promettenti, potrei decidere di rinunciare sull'attuazione ora;
-
Ho bisogno di fornire cifre in una pubblicazione il cui termine non ho alcun controllo.
Soluzione
su OSX (ARM, Intel e PowerPC), che si desidera utilizzare mach_absolute_time( )
:
#include <mach/mach_time.h>
#include <stdint.h>
// Utility function for getting timings in nanoseconds.
double machTimeUnitsToNanoseconds(uint64_t mtu) {
static double mtusPerNanosecond = 0.0;
if (0.0 == mtusPerNanosecond) {
mach_timebase_info_data_t info;
if (mach_timebase_info(&info)) {
// Handle an error gracefully here, whatever that means to you.
// If you do get an error, something is seriously wrong, so
// I generally just report it and exit( ).
}
mtusPerNanosecond = (double)info.numer / info.denom;
}
return mtu * mtusPerNanosecond;
}
// In your code:
uint64_t startTime = mach_absolute_time( );
// Stuff that you want to time.
uint64_t endTime = mach_absolute_time( );
double elapsedNanoseconds = machTimeUnitsToNanoseconds(endTime - startTime);
Si noti che non c'è bisogno di limitare a un core per questo. Le maniglie del sistema operativo il fix-up richiesto dietro le quinte per mach_absolute_time( )
per dare risultati meaninful in un multi-core (e multi-socket) ambiente.
Altri suggerimenti
I nuclei stanno tornando i valori corretti per sincronizzati "rtdsc". Se si dispone di una macchina multipresa si deve fissare il processe ad una presa di corrente. Questo non è il problema.
Il problema principale è che lo scheduler sta facendo i dati inaffidabili. V'è una certa API prestazioni per Linux Kernel> 2.6.31, ma non l'ho guardato. Di Windows> Vista sta facendo un ottimo lavoro qui, utilizzare QueryThreadCycleTime e QueryProcessCycleTime.
Non sono sicuro di OSX, ma per quanto ne so "mach_absolute_time" non regolare il tempo previsto.