Отрицательные измерения тактового цикла с обратной связью 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;
}

Ответы на вопрос(9)

Ваш ответ на вопрос