首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于Intel Xeon X5550的Linux下不稳定的__rdtscp校准

基于Intel Xeon X5550的Linux下不稳定的__rdtscp校准
EN

Stack Overflow用户
提问于 2016-03-19 11:47:30
回答 2查看 335关注 0票数 2

我试图使用__rdtscp的trying函数来度量时间间隔。目标平台是Linux x64,CPU Intel Xeon X5550。虽然为这个处理器设置了constant_tsc标志,但是校准__rdtscp会得到非常不同的结果:

代码语言:javascript
复制
$ 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)。这种不稳定性不适合任何测量。

下面是代码(gcc 4.9.3,运行在Oracle Linux 6.6上,内核3.8.13-55.1.2.el6uek.x86_64):

代码语言:javascript
复制
// 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;
}

当我在Windows7,i7-4470,VS2015下运行非常类似的程序时,校准结果是相当稳定的,仅在最后一个数字上相差很小。

所以问题是-那是什么问题?是CPU问题、Linux问题还是我的代码问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-19 12:19:01

这绝对是我的代码(或gcc)的问题。编译器优化出了用s = 1000000替换它的循环。

为了防止gcc优化这一校准回路,应改变如下:

代码语言:javascript
复制
for (size_t i = 0; i < 1000000; ++i) s += i;

或者更简单和正确的方式(感谢哈尔):

代码语言:javascript
复制
for (volatile size_t i = 0; i < 1000000; ++i);
票数 2
EN

Stack Overflow用户

发布于 2016-03-19 12:41:07

如果您也不确保cpu是孤立的,其他的抖动源就会出现。您确实希望避免将另一个进程安排在该核心上。此外,理想情况下,您运行的是一个没有痒的内核,这样您就永远不会在内核上运行内核代码。在上面的代码中,我想只有当你不走运的时候,才能在调用clock_gettime()和__rdtscp之间切换到滴答或上下文。

使s易失性是另一种克服这种编译器优化的方法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36101311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档