什么被认为是缓存中的高未命中 rate/low 命中率?
What is considered a high miss rate/low hit rate in caches?
我一直在尝试分析我在我的机器上作为小型内存测试编写的一些代码,并且通过使用 perf 我注意到:
Performance counter stats for './MemBenchmark':
15,980 LLC-loads
8,714 LLC-load-misses # 54.53% of all LL-cache hits
10.002878281 seconds time elapsed
基准测试的整个想法是 'stress' 内存,所以在我的书中,我认为越高的未命中率就越好。
编辑:Perf 中是否有允许将文件分析到不同部分的功能?例如如果 main() 包含三个 for 循环,是否可以单独分析每个循环以查看 LLC 加载未命中的次数?
请记住,LLC 负载仅计算 L1d 和 L2 中丢失的负载。作为总负载的一小部分 (L1-dcache-loads
),对于整个缓存层次结构来说,这可能是一个 非常 好的命中率(由于良好的局部性 and/or 成功预取。)
(,所以最后一级是共享的 L3;L1 和 L2 是私有的每核缓存。在只有 2 级缓存的 CPU 上,LLC 将是 L2 .)
只有 9k 次访问必须一直到 DRAM 10 秒非常非常好。
低 LLC 命中率和如此低的总 LLC 负载告诉您,您的工作负载对其大部分访问具有良好的局部性,但确实未命中的访问通常必须一直到 DRAM,并且仅其中一半受益于 L3 缓存。
相关:, and see @BeeOnRope's answer on 他说 LLC 未命中的绝对数量对性能至关重要。
局部性较差的算法会产生 很多 的 L2 未命中,并且通常会产生很多 L3 命中(很可能具有很高的 L3 命中率),但也有很多总L3 未命中,因此流水线在等待内存的大部分时间都停滞不前。
What metric could you suggest to measure how my program performs in terms of stressing the memory?
您想知道您的程序导致了多少内存流量,包括预取吗?即它可能对其他竞争内存带宽的程序产生什么样的影响? offcore_requests.all_requests
可以告诉您有多少请求(包括 L2 预取、页面遍历以及加载和存储,但不包括 L3 预取)通过 L2 到达共享 L3 缓存,无论它们是否命中共享 L3。 (Use the ocperf.py
wrapper for perf
。我的 Skylake 有那个事件;IDK 如果你的 Nehalem 会的话。)
就检测您的代码是否存在内存瓶颈而言,LLC-load-misses
每秒作为绝对度量是合理的。 Skylake 至少有一个 cycle_activity.stalls_l3_miss
来计算没有执行 uops 并且有一个突出的 L3 未命中的周期。如果这超过总周期的百分之几,您需要考虑避免这些停顿。
(我自己还没有尝试使用这些事件来学习任何东西,它们可能不是最有用的建议。在分析时很难知道问自己正确的问题;有很多事件你可以看看但是使用它们来学习一些可以帮助您弄清楚如何更改代码的东西很困难。对您的代码如何使用内存有一个很好的心理了解很有帮助,所以您知道要寻找什么。对于这样一个一般性的问题,很难说太多。)
Is there a way you could suggest that can break down the benchmark file to see which loops are causing the most stress?
您可以使用 perf record -e whatever
/ perf report -Mintel
对您想要的任何事件进行基于统计样本的分析,以查看热点在哪里。
但是对于缓存未命中,有时 责备 在于某些代码在数组上循环并逐出大量有价值的数据,而不是触及仍然存在的有价值数据的代码热
如果硬件预取完成它的工作,一个大数组的循环可能不会看到很多缓存未命中。
linux perf: how to interpret and find hotspots。如果您不确切知道程序中哪些是慢的,哪些是快的,那么使用堆栈采样可能非常有用。对每个事件的调用堆栈进行采样将向您显示调用树中高处的哪个函数调用要为它的被调用者所做的所有工作负责。首先避免该调用比稍微加快它调用的函数要好得多。
(避免工作,而不仅仅是用更好的蛮力做同样的工作。仔细应用现代 CPU 可以承受 AVX2 的最大蛮力是有用的 after 你已经确定你一开始就无法避免这样做。)
我一直在尝试分析我在我的机器上作为小型内存测试编写的一些代码,并且通过使用 perf 我注意到:
Performance counter stats for './MemBenchmark':
15,980 LLC-loads
8,714 LLC-load-misses # 54.53% of all LL-cache hits
10.002878281 seconds time elapsed
基准测试的整个想法是 'stress' 内存,所以在我的书中,我认为越高的未命中率就越好。
编辑:Perf 中是否有允许将文件分析到不同部分的功能?例如如果 main() 包含三个 for 循环,是否可以单独分析每个循环以查看 LLC 加载未命中的次数?
请记住,LLC 负载仅计算 L1d 和 L2 中丢失的负载。作为总负载的一小部分 (L1-dcache-loads
),对于整个缓存层次结构来说,这可能是一个 非常 好的命中率(由于良好的局部性 and/or 成功预取。)
(
只有 9k 次访问必须一直到 DRAM 10 秒非常非常好。
低 LLC 命中率和如此低的总 LLC 负载告诉您,您的工作负载对其大部分访问具有良好的局部性,但确实未命中的访问通常必须一直到 DRAM,并且仅其中一半受益于 L3 缓存。
相关:
局部性较差的算法会产生 很多 的 L2 未命中,并且通常会产生很多 L3 命中(很可能具有很高的 L3 命中率),但也有很多总L3 未命中,因此流水线在等待内存的大部分时间都停滞不前。
What metric could you suggest to measure how my program performs in terms of stressing the memory?
您想知道您的程序导致了多少内存流量,包括预取吗?即它可能对其他竞争内存带宽的程序产生什么样的影响? offcore_requests.all_requests
可以告诉您有多少请求(包括 L2 预取、页面遍历以及加载和存储,但不包括 L3 预取)通过 L2 到达共享 L3 缓存,无论它们是否命中共享 L3。 (Use the ocperf.py
wrapper for perf
。我的 Skylake 有那个事件;IDK 如果你的 Nehalem 会的话。)
就检测您的代码是否存在内存瓶颈而言,LLC-load-misses
每秒作为绝对度量是合理的。 Skylake 至少有一个 cycle_activity.stalls_l3_miss
来计算没有执行 uops 并且有一个突出的 L3 未命中的周期。如果这超过总周期的百分之几,您需要考虑避免这些停顿。
(我自己还没有尝试使用这些事件来学习任何东西,它们可能不是最有用的建议。在分析时很难知道问自己正确的问题;有很多事件你可以看看但是使用它们来学习一些可以帮助您弄清楚如何更改代码的东西很困难。对您的代码如何使用内存有一个很好的心理了解很有帮助,所以您知道要寻找什么。对于这样一个一般性的问题,很难说太多。)
Is there a way you could suggest that can break down the benchmark file to see which loops are causing the most stress?
您可以使用 perf record -e whatever
/ perf report -Mintel
对您想要的任何事件进行基于统计样本的分析,以查看热点在哪里。
但是对于缓存未命中,有时 责备 在于某些代码在数组上循环并逐出大量有价值的数据,而不是触及仍然存在的有价值数据的代码热
如果硬件预取完成它的工作,一个大数组的循环可能不会看到很多缓存未命中。
linux perf: how to interpret and find hotspots。如果您不确切知道程序中哪些是慢的,哪些是快的,那么使用堆栈采样可能非常有用。对每个事件的调用堆栈进行采样将向您显示调用树中高处的哪个函数调用要为它的被调用者所做的所有工作负责。首先避免该调用比稍微加快它调用的函数要好得多。
(避免工作,而不仅仅是用更好的蛮力做同样的工作。仔细应用现代 CPU 可以承受 AVX2 的最大蛮力是有用的 after 你已经确定你一开始就无法避免这样做。)