Misure del ciclo di orologio negativo con rdtsc back-to-back?

Sto scrivendo un codice C per misurare il numero di cicli di clock necessari per acquisire un semaforo. Sto usando rdtsc, e prima di fare la misura sul semaforo, chiamo rdtsc due volte consecutive, per misurare il sovraccarico. Lo ripeto molte volte, in un ciclo for, quindi utilizzo il valore medio come overhead di rdtsc.

È corretto, per usare il valore medio, prima di tutto?

Tuttavia, il grosso problema qui è che a volte ottengo valori negativi per l’overhead (non necessariamente quello medio, ma almeno quelli parziali all’interno del ciclo for).

Ciò influisce anche sul calcolo consecutivo del numero di cicli cpu necessari per l’operazione sem_wait() , che a volte risulta essere negativo. Se quello che ho scritto non è chiaro, qui c’è una parte del codice su cui sto lavorando.

Perché ricevo tali valori negativi?


(nota del redattore: vedi Ottenere il conteggio del ciclo della CPU? per un modo corretto e portatile di ottenere il timestamp completo a 64 bit. Un vincolo asm "=A" otterrà solo i 32 bit bassi o alti quando compilato per x86-64, a seconda di se l’assegnazione del registro avviene per scegliere RAX o RDX per l’output uint64_t . Non selezionerà edx:eax .)

(Seconda nota del redattore: oops, questa è la risposta al motivo per cui otteniamo risultati negativi. Vale comunque la pena lasciare una nota qui come avvertimento per non copiare questa implementazione rdtsc .)


 #include  #include  #include  #include  #include  static inline uint64_t get_cycles() { uint64_t t; // editor's note: "=A" is unsafe for this in x86-64 __asm volatile ("rdtsc" : "=A"(t)); return t; } int num_measures = 10; int main () { int i, value, res1, res2; uint64_t c1, c2; int tsccost, tot, a; tot=0; for(i=0; i<num_measures; i++) { c1 = get_cycles(); c2 = get_cycles(); tsccost=(int)(c2-c1); if(tsccost<0) { printf("#### ERROR!!! "); printf("rdtsc took %d clock cycles\n", tsccost); return 1; } tot = tot+tsccost; } tsccost=tot/num_measures; printf("rdtsc takes on average: %d clock cycles\n", tsccost); return EXIT_SUCCESS; }