我正在使用以下代码进行测试:
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\复制读取命中率%
- \Cache\复制读取/秒
- \内存\页面错误/秒
表演结束后,结果如下: http://pastebin.com/L78Pjs9W
有人可以解释一下为什么它仍然会出现页面错误吗? 此外,我还运行了相同的程序,但 i 和 j 颠倒了,以尝试滥用缓存。 由于我意识到我的 CPU 可能会检测到跨步访问,所以我也尝试了随机访问,但这些 Windows 计数器的结果仍然没有太大变化。
我也在 VTune Amplifier 中尝试过这个,给了我类似的、奇怪的结果。 随机访问或翻转 i 和 j 可以减少缓存丢失,使用以下方法: 测试[i][j] = 20; 不给我 0 次缓存未命中(或关闭) 我正在使用以下计数器:
- L2_RQSTS_MISS
- L2_RQSTS_REFERENCES
所有 3 种方法为我提供了大约 7,000,000 次引用和 3,800,000 次未命中。在 25 秒的样本上。 我预计 [i][j] 访问几乎不会丢失,因为它具有空间局部性并且是可预测的。
我使用的计数器是否正确,有什么提示吗?
最佳答案
您有一个包含 25,000,000 个元素的数组,即 100M。您还没有说明您的 L2 缓存大小,但它可能约为几兆,那么为什么您会期望接近 0 缓存未命中呢?您的数据不适合您的缓存,因此您需要在输出中交换数据(也称为缓存未命中)。
在一次运行中,外部 while 执行了多少个循环?
我建议首先修复一些迭代,这些迭代的运行时间大约是您愿意等待的时间。这样您的所有运行都是一致的。
您的随机探测运行可能会执行更少的迭代,因为它们更频繁地错过缓存。事实上,考虑到您似乎正在根据时间停止基准测试,并且您的示例的瓶颈是缓存未命中,您可能会在类似数量的缓存未命中后停止运行,并且没有意识到良好的订单正在执行更多迭代。
关于c++ - 使用 VS2012/VTune 进行缓存分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24929097/