1

我正在测试库中几个函数的延迟。为此,我在进入和退出时使用 rdtsc(),我跟踪生成的 rdtsc 值、运行的最小值、最大值和调用次数(以获取平均值)。当我查看输出图时,我看到平均大约 100 个周期,但峰值大约为 20000 个周期或类似的东西(这似乎比函数中 3 或 4 个分支的简单分支错误预测要糟糕得多)。我运行了cachegrind,得到了这样的输出:

==14038==
==14038== I   refs:      2,260,149,383
==14038== I1  misses:           10,408
==14038== LLi misses:            3,978
==14038== I1  miss rate:          0.00%
==14038== LLi miss rate:          0.00%
==14038==
==14038== D   refs:      1,100,962,403  (773,471,444 rd   + 327,490,959 wr)
==14038== D1  misses:           26,419  (     13,447 rd   +      12,972 wr)
==14038== LLd misses:           15,446  (      5,701 rd   +       9,745 wr)
==14038== D1  miss rate:           0.0% (        0.0%     +         0.0%  )
==14038== LLd miss rate:           0.0% (        0.0%     +         0.0%  )
==14038==
==14038== LL refs:              36,827  (     23,855 rd   +      12,972 wr)
==14038== LL misses:            19,424  (      9,679 rd   +       9,745 wr)
==14038== LL miss rate:            0.0% (        0.0%     +         0.0%  )
==14038==
==14038== Branches:        327,248,773  (297,539,058 cond +  29,709,715 ind)
==14038== Mispredicts:         980,262  (    978,639 cond +       1,623 ind)
==14038== Mispred rate:            0.2% (        0.3%     +         0.0%   )

错误预测和分支未命中率如此之低,这让我想知道发生了什么……我怎么可能经常看到如此高的延迟测量,大约 20K 周期?我还可以研究哪些东西来解开这个谜团?会是什么呢?

事实上,令人难以置信的是,其中一个 rdtsc 测量值仅包含如下内容:

if(memberVarBool_)
{
    memberVarPtr->smallFuncWithThreeIntAssignsAndstdmax;
}

这个家伙向我展示了很多“25”周期的东西,这很有意义,但也有很多大约 2000 个周期的案例!

更新:我刚刚切换到使用 gettimeofday 来测量以纳秒为单位的延迟,希望避免特定于 rdtsc 的问题并且仍然看到相同的东西......有没有办法可以在我的测量中避免抢占和外部或过程影响?

4

2 回答 2

1

您如何确保操作系统不会在两次调用 rdtsc() 之间安排另一个任务/进程?如何防止在两次调用 rdtsc() 之间发生硬件中断?

这两种情况都会导致两个读数之间的差异似乎出现峰值。

于 2012-07-20T20:34:59.900 回答
0

如果您保留原始样本,您可以绘制它们并忽略异常值,或者采用中值而不是平均值/平均值。顺便说一句,以及抢占 - rdtsc 可能误报间隔的另一个原因是您的线程移动内核:每个内核都有自己的 TSC 寄存器,并且在许多盒子上,它们在任何时间点都不会同步到相同的值。将流程固定到特定核心会有所帮助。您可能需要成为 root 才能禁用硬件中断,而且我不确定它是如何在用户进程上下文中完成的。

另外,仅仅因为某些东西名义上返回纳秒并不意味着它在实践中会这样做:许多这样的函数在一些较慢的驱动程序下跳跃了数百万纳秒;重复调用该函数将返回相同的值,直到它再次跳转。

于 2012-07-20T22:30:21.873 回答