0

我正在尝试使用 VsPerfCmd.exe 来分析检测本机应用程序中的分支预测错误和最后一级缓存未命中。

设置就像在tin上所说的那样工作,但我得到的结果似乎并不明智。例如,一个总是接触 24MB 数据集的函数被报告为在被调用 ~2000 次时只会导致 ~700 次缓存未命中。现在让我考虑一下 - 该函数线性遍历两个 12 字节元素的 1024*1024 元素数组。对于每个元素,它随机决定是否需要它之前或之后的元素 1024 个索引的信息。这意味着为了不产生任何高速缓存未命中,CPU 必须始终在高速缓存中拥有至少三个 1024*12 字节的部分。此外,在每次迭代之后,该过程使用 sleep() 产生 CPU 大约 8 毫秒。我无法想象任何硬件预取器做得这么好。

这种愚蠢的数据量怎么不会产生比 VsPerfCmd 说的更多的最后一级缓存未命中?尽管我的 i7 有 8MB 的共享 L3 缓存,但这似乎不太可能。任何人都可以分享他们对这里可能发生的事情的看法吗?当然,“VsPerfCmd.exe 糟透了”将是一个有效的答案,但如果有人要这么说,我至少想听听有人有类似的经历作为这个断言的基础。

4

2 回答 2

2
于 2012-04-14T09:32:17.080 回答
2

首先 - 硬件 LLC 未命中计数器(我们称其为)实际上不会计算您的特定应用程序中的 LLC 未命中数。它的作用是计算所有 LLC 未命中并将该数字与预设阈值(称为 SAV - 值后样本,通常为数千甚至数百万)进行比较。如果当前计数等于 SAV,则会引发中断,此时指向的任何 IP 都将保存在跟踪中,与计数器和时间戳一起(例如,使跟踪合理)。如果此 IP 指向您模块中的指令,那么所有这些缓存未命中都归因于您的模块/功能/指令。因此,您看到的结果图片不是真实的,而是统计上正确的。我没有使用过 VsPerfCmd,但可以帮助您检查它为 LLC 未命中设置的 SAV。如果它'

然后是您的应用程序工作负载和工作集的主题。3 x 1024 x 12B 只有 36KB,这对于 8MB LLC 来说不算什么。如果算法均匀地来回跳跃,而不总是向前或向后跳跃,那么它只是经常使用的 24 MB 的一小部分,这意味着最热门的数据也很可能适合 LLC。此外,CPU 只能看到称为高速缓存行的块中的内存,这些块长 64 字节。因此,每当您的算法向前或向后跳转以访问接下来的 12 个字节时,都会将 52 个相邻字节加载到 L1 中,因此如果跳转后的下一步是 *(ptr++),则不会导致缓存未命中。让 CPU 8 毫秒不应影响缓存性能,除非您怀疑为下一个时间片安排的线程正在执行其他内存密集型操作,这将导致您的数据缓存行被驱逐。否则,如果只是一些在后台运行的操作系统线程仅触及几个字节,那么就不应该发生大规模缓存驱逐。

于 2012-04-26T09:44:13.733 回答