我正在使用以下代码进行测试:
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计数器:
表演后的结果如下: http://pastebin.com/L78Pjs9W
有人可能会说明为什么它仍会出现Page故障? 此外,我已经运行相同的程序与i和j反转尝试滥用缓存。 由于我意识到我的CPU可能会检测到跨步访问,我也尝试了随机访问,但这些Windows计数器的结果仍然没有太大变化。
我也在VTune放大器中试过这个,给我类似的奇怪结果。 使用以下方法随机访问或翻转i和j可以减少缓存未命中率: test [i] [j] = 20; 不给我0 cachemiss(或关闭) 我使用以下计数器:
所有3种方法都给了我大约7,000,000个引用和3,800,000个未命中。在一个25秒的样本。 我预计[i] [j]访问几乎没有错过,因为它具有空间局部性并且是可预测的。
我使用正确的计数器,任何提示吗?
答案 0 :(得分:3)
你有一个25,000,000个元素的数组,即100M。你还没有说明你的L2缓存大小,但它可能只有几个Megs的数量级,所以你为什么期望接近0个缓存未命中?您的数据不适合您的缓存,因此您需要交换数据(也就是缓存未命中)。
在你的一次跑步中你的外线执行了多少次循环?
我建议首先修复一些运行大约你愿意等待的时间的迭代。这样你的所有跑步都是一致的。
可能是您的随机探测运行的迭代次数要少得多,因为它们会更频繁地错过缓存。事实上,鉴于您似乎正在停止基于时间的基准测试,并且您的示例的瓶颈是缓存未命中,您可能会在类似数量的缓存未命中后停止运行,并且没有意识到良好的订单正在执行更多迭代。