我正在测试库中几个函数的延迟。为此,我在进入和退出时使用 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 的问题并且仍然看到相同的东西......有没有办法可以在我的测量中避免抢占和外部或过程影响?