Negative Taktmessungen mit Back-to-Back-RDSC?
Ich schreibe einen C-Code zum Messen der Anzahl von Taktzyklen, die zum Erfassen eines Semaphors benötigt werden. Ich verwende rdtsc, und bevor ich die Messung am Semaphor durchführe, rufe ich rdtsc zwei Mal hintereinander auf, um den Overhead zu messen. Ich wiederhole dies viele Male in einer for-Schleife und verwende dann den Durchschnittswert als rdtsc-Overhead.
Ist das richtig, um zunächst den Mittelwert zu verwenden?
Das große Problem hierbei ist jedoch, dass ich manchmal negative Werte für den Overhead erhalte (nicht unbedingt den gemittelten, sondern zumindest die Teilwerte innerhalb der for-Schleife).
Dies wirkt sich auch auf die fortlaufende Berechnung der Anzahl der CPU - Zyklen aus, die für das System benötigt werdensem_wait()
Operation, die manchmal auch negativ ausfällt. Wenn das, was ich geschrieben habe, nicht klar ist, gibt es hier einen Teil des Codes, an dem ich arbeite.
Warum bekomme ich so negative Werte?
(Anmerkung der Redaktion: sieheCPU-Zykluszahl ermitteln? für eine korrekte und tragbare Methode, um den vollständigen 64-Bit-Zeitstempel zu erhalten. Ein"=A"
Die asm-Einschränkung erhält nur die niedrigen oder hohen 32 Bit, wenn sie für x86-64 kompiliert wird. Dies hängt davon ab, ob die Registerzuweisung für RAX oder RDX erfolgtuint64_t
Ausgabe. Es wird nicht holenedx:eax
.)
(2. Anmerkung des Herausgebers: Hoppla, das ist die Antwort darauf, warum wir negative Ergebnisse erhalten. Es lohnt sich immer noch, hier eine Anmerkung zu hinterlassen, um zu warnen, dies nicht zu kopierenrdtsc
Implementierung.)
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
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;
}