Я пытаюсь измерить производительность функции.
double microbenchmark_get_sqrt_latency()
{
myInt64 start, end;
list<double> cyclesList;
int num_runs = 40;
double cycles = 0.;
double multiplier = 1.;
double x = 500;
// Repeat the measurement 1000 times
for (size_t i = 0; i < 1000; i++)
{
// Measuring...
start = start_tsc();
for (size_t j = 0; j < num_runs; ++j)
{
sqrtsd(x);
}
// Maybe this instruction is called before the loop ends? somehow?
end = stop_tsc(start);
// Doesn't return the correct number of cycles because
cycles = ((double)end) / num_runs;
cyclesList.push_back(cycles);
}
cyclesList.sort();
auto it = cyclesList.begin();
std::advance(it, cyclesList.size() / 2);
return *it;
}
Проблема здесь в том, что для переменной end
, которая представляет число циклов, которые произошли с момента первого rdtsc
инструкция всегда равна 22-24, даже когда num_runs
изменяется до 10000. У меня нет объяснения этому, за исключением того, что, возможно, инструкция перемещается после первой итерации для l oop.
* 1008 Флаги компилятора и компилятора, которые я использую:
-O3 -fno-tree-vectorize -march=skylake -std=c++17
Вот реализация start_tsc()
и stop_tsc()
:
#define RDTSC(cpu_c) \
ASM VOLATILE("rdtsc" \
: "=a"((cpu_c).int32.lo), "=d"((cpu_c).int32.hi))
#define CPUID() \
ASM VOLATILE("cpuid" \
: \
: "a"(0) \
: "bx", "cx", "dx")
unsigned long long start_tsc(void)
{
tsc_counter start;
CPUID();
RDTSC(start);
return COUNTER_VAL(start);
}
unsigned long long stop_tsc(unsigned long long start)
{
tsc_counter end;
RDTSC(end);
CPUID();
return COUNTER_VAL(end) - start;
}
Что не так с кодом? Я ожидаю, что переменная end
будет пропорциональна num_runs
, но ее здесь нет. Есть идеи?