使用VS2012 / VTune进行缓存分析

时间:2014-07-24 08:47:27

标签: c++ caching profiling

我正在使用以下代码进行测试:

const int num = 5000;
int test[num][num];

int _tmain(int argc, _TCHAR* argv[])
{
    while(true)
    {
        for (int i = 0; i < num; i++)
        {
            for (int j = 0; j < num; j++)
            {
                test[j][i] = 10;
            }
        }
    }
}

我有以下Windows计数器:

  • \ Cache \ Copy Read Hits%
  • \ Cache \ Copy Read / sec
  • \ Memory \ Page Faults / sec

表演后的结果如下: http://pastebin.com/L78Pjs9W

有人可能会说明为什么它仍会出现Page故障? 此外,我已经运行相同的程序与i和j反转尝试滥用缓存。 由于我意识到我的CPU可能会检测到跨步访问,我也尝试了随机访问,但这些Windows计数器的结果仍然没有太大变化。

我也在VTune放大器中试过这个,给我类似的奇怪结果。 使用以下方法随机访问或翻转i和j可以减少缓存未命中率:     test [i] [j] = 20; 给我0 cachemiss(或关闭) 我使用以下计数器:

  • L2_RQSTS_MISS
  • L2_RQSTS_REFERENCES

所有3种方法都给了我大约7,000,000个引用和3,800,000个未命中。在一个25秒的样本。 我预计[i] [j]访问几乎没有错过,因为它具有空间局部性并且是可预测的。

我使用正确的计数器,任何提示吗?

1 个答案:

答案 0 :(得分:3)

你有一个25,000,000个元素的数组,即100M。你还没有说明你的L2缓存大小,但它可能只有几个Megs的数量级,所以你为什么期望接近0个缓存未命中?您的数据不适合您的缓存,因此您需要交换数据(也就是缓存未命中)。

在你的一次跑步中你的外线执行了多少次循环?

我建议首先修复一些运行大约你愿意等待的时间的迭代。这样你的所有跑步都是一致的。

可能是您的随机探测运行的迭代次数要少得多,因为它们会更频繁地错过缓存。事实上,鉴于您似乎正在停止基于时间的基准测试,并且您的示例的瓶颈是缓存未命中,您可能会在类似数量的缓存未命中后停止运行,并且没有意识到良好的订单正在执行更多迭代。