Отрицательные измерения тактового цикла с обратной связью rdtsc?
Я пишу код C для измерения количества тактов, необходимых для получения семафора. Я использую rdtsc, и перед выполнением измерения на семафоре я вызываю rdtsc два раза подряд, чтобы измерить издержки. Я повторяю это много раз в цикле for, а затем я использую среднее значение в качестве издержек rdtsc.
Правильно ли, прежде всего, использовать среднее значение?
Тем не менее, большая проблема здесь заключается в том, что иногда я получаю отрицательные значения для служебных данных (не обязательно усредненных, но по крайней мере частичных внутри цикла for).
Это также влияет на последовательный расчет количества циклов процессора, необходимых дляsem_wait()
операция, которая иногда также оказывается отрицательной. Если то, что я написал, неясно, здесь есть часть кода, над которой я работаю.
Почему я получаю такие отрицательные значения?
(примечание редактора: см.Получить количество тактов процессора? для правильного и портативного способа получения полной 64-битной метки времени."=A"
Ограничение asm будет получать только младшие или старшие 32 бита при компиляции для x86-64, в зависимости от того, происходит ли при распределении регистров выбор RAX или RDX дляuint64_t
выход. Это не выберетedx:eax
.)
(2-е примечание редактора: ой, это ответ на вопрос, почему мы получаем отрицательные результаты. Все же стоит оставить здесь заметку в качестве предупреждения, чтобы не копировать этоrdtsc
реализация.)
#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;
}