__rdtscp
intrinsinc関数を使用して時間間隔を測定しようとしています。ターゲットプラットフォームはLinux x64、CPU Intel Xeon X5550です。Intel Xeon X5550のLinuxでは__rdtscp較正が不安定です
$ taskset -c 1 ./ticks
Ticks per usec: 256
$ taskset -c 1 ./ticks
Ticks per usec: 330.667
$ taskset -c 1 ./ticks
Ticks per usec: 345.043
$ taskset -c 1 ./ticks
Ticks per usec: 166.054
$ taskset -c 1 ./ticks
Ticks per usec: 256
$ taskset -c 1 ./ticks
Ticks per usec: 345.043
$ taskset -c 1 ./ticks
Ticks per usec: 256
$ taskset -c 1 ./ticks
Ticks per usec: 330.667
$ taskset -c 1 ./ticks
Ticks per usec: 256
$ taskset -c 1 ./ticks
Ticks per usec: 330.667
$ taskset -c 1 ./ticks
Ticks per usec: 330.667
$ taskset -c 1 ./ticks
Ticks per usec: 345.043
$ taskset -c 1 ./ticks
Ticks per usec: 256
$ taskset -c 1 ./ticks
Ticks per usec: 125.388
$ taskset -c 1 ./ticks
Ticks per usec: 360.727
$ taskset -c 1 ./ticks
Ticks per usec: 345.043
我々はプログラムの実行の間の差が3倍(125から360)までとすることができる見ることができるように:constant_tsc
フラグは、このプロセッサのために設定されているが、__rdtscp
較正は非常に異なった結果を与えます。このような不安定性は、いかなる測定にも不適切である。ここで
// g++ -O3 -std=c++11 -Wall ticks.cpp -o ticks
#include <x86intrin.h>
#include <ctime>
#include <cstdint>
#include <iostream>
int main()
{
timespec start, end;
uint64_t s = 0;
const double rdtsc_ticks_per_usec = [&]()
{
unsigned int dummy;
clock_gettime(CLOCK_MONOTONIC, &start);
uint64_t rd_start = __rdtscp(&dummy);
for (size_t i = 0; i < 1000000; ++i) ++s;
uint64_t rd_end = __rdtscp(&dummy);
clock_gettime(CLOCK_MONOTONIC, &end);
double usec_dur = double(end.tv_sec) * 1E6 + end.tv_nsec/1E3;
usec_dur -= double(start.tv_sec) * 1E6 + start.tv_nsec/1E3;
return (double)(rd_end - rd_start)/usec_dur;
}();
std::cout << s << std::endl;
std::cout << "Ticks per usec: " << rdtsc_ticks_per_usec << std::endl;
return 0;
}
、i7-4470、VS2015較正の結果はかなり安定していて、最後の桁の小さな差のみです。
だから、その問題は何ですか?それはCPUの問題、Linuxの問題または私のコードの問題ですか?
'constant_tsc'は、TSCがCPUの実際の周波数に固定されていないことを意味します。最適化されたタイミングループの問題のほかに、ウォームアップループを実行して、タイミングループが始まる前に最大ターボクロック速度までCPUを取得する必要があります。 –