Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Valgrind输出和rdtsc不一致…为什么会这样?_C++_Optimization_Valgrind - Fatal编程技术网

C++ Valgrind输出和rdtsc不一致…为什么会这样?

C++ Valgrind输出和rdtsc不一致…为什么会这样?,c++,optimization,valgrind,C++,Optimization,Valgrind,我正在测试库中几个函数的延迟。为了做到这一点,我在进入和退出时使用rdtsc(),跟踪结果rdtsc值、运行的最小值、最大值和调用次数(以获得平均值)。当我查看输出图时,我看到平均约100个周期,但峰值约20000个周期或类似的干扰(这似乎比函数中3或4个分支的简单分支预测失误严重得多)。我运行cachegrind,得到如下输出: ==14038== ==14038== I refs: 2,260,149,383 ==14038== I1 misses: 10

我正在测试库中几个函数的延迟。为了做到这一点,我在进入和退出时使用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%   )
if(memberVarBool_)
{
    memberVarPtr->smallFuncWithThreeIntAssignsAndstdmax;
}
哪里的预测失误率和分支未命中率如此之低,这让我想知道到底发生了什么。我怎么可能经常看到20K周期的高延迟测量?我还可以做些什么来解开这个谜?可能是什么

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

==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%   )
if(memberVarBool_)
{
    memberVarPtr->smallFuncWithThreeIntAssignsAndstdmax;
}
这家伙向我展示了很多“25”个周期的东西,这很有意义,但也有很多关于2000个周期的例子


更新:我刚刚改用gettimeofday以纳秒为单位测量延迟,希望避免rdtsc特有的问题,但仍然看到相同的东西……有没有办法在我的测量中避免抢占和外部或进程影响?

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


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

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


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

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


另外,名义上返回纳秒并不意味着实际返回纳秒:许多这样的函数会随着较慢的滴答声驱动程序跳跃数亿纳秒;对函数的重复调用将返回相同的值,直到它再次跳转。

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



另外,名义上返回纳秒并不意味着实际返回纳秒:许多这样的函数会随着较慢的滴答声驱动程序跳跃数亿纳秒;重复调用该函数将返回相同的值,直到它再次跳转。

您是否在实时操作系统上运行?有很多事情可能会中断您的进程。您的进程是否曾被抢占或进行过系统调用?@Chad,我将尝试使用ulimit-r99运行。但我想排除代码本身的实际低效或问题。@Plasmah我运行的代码段没有系统调用…不确定程序的抢占,但这是否是罪魁祸首?@PalaceChan:如果您的程序被抢占并且没有安排100000个周期,然后你的计时将显示那100000个周期。你是在实时操作系统上运行的吗?有很多事情可能会中断您的进程。您的进程是否曾被抢占或进行过系统调用?@Chad,我将尝试使用ulimit-r99运行。但我想排除代码本身的实际低效或问题。@Plasmah我运行的代码段没有系统调用…不确定程序的抢占,但这是否是罪魁祸首?@PalaceChan:如果您的程序被抢占并且没有安排100000个周期,然后你的计时将显示那100000个循环..使用ulimit-R99运行会有助于防止这种情况吗?或者我该如何归因于此或避免此问题?使用ulimit-r99运行是否有助于防止此问题?或者我怎样才能归因于这个或者避免这个?有趣的是,在它再次跳转之前,这是关于同一个值的什么?我在纳秒的时候观察到了相当多的重复值!非常具体的数量,比如1000。我之所以关注最大值,是因为我担心它们看起来如此频繁(根据我开始质疑的“计时数据…”…ulimit-R99是否保证没有先发制人?有没有一种方法可以在非常低的延迟下测量“用户时间”,我可以研究吗?@PalaceChan:这正是问题所在——如果你在一个紧循环中调用一个操作系统计时函数,你会多次得到完全相同的值,然后它会以实际更新周期的倍数跳跃(通常乘数为1,但如果出现线程抢占、硬件中断等情况,则乘数可能会更大)。如果您确实需要了解分支预测失误、缓存线暂停等的成本,则最大值非常重要。人们通常认为,当这对他们的总体程序吞吐量无关紧要时,他们会这样做,但您可能会这样做;-)(
ulimit-r
本身不会有帮助。。。您需要将操作系统设置为实时支持,并使应用程序请求具有更高的优先级。“用户”