perf stat 输出的解释
Interpretation of perf stat output
我开发了一种代码,可以将大型二维图像(高达 64MPixels)作为输入,并且:
- 对每行应用过滤器
- 转置图像(使用分块以避免大量缓存未命中)
- 对图像的列(现在是行)应用过滤器
- 将过滤后的图像转置回去进行其他计算
虽然它没有改变什么,但为了我的问题的完整性,过滤应用了离散小波变换并且代码是用 C 编写的。
我的最终目标是让这个 运行 尽可能快。通过使用阻塞矩阵转置、矢量化、多线程、编译器友好代码等,我到目前为止的加速超过 10 倍
回答我的问题:我所拥有的代码的最新分析统计数据(使用 perf stat -e
)让我很困扰。
76,321,873 cache-references
8,647,026,694 cycles # 0.000 GHz
7,050,257,995 instructions # 0.82 insns per cycle
49,739,417 cache-misses # 65.171 % of all cache refs
0.910437338 seconds time elapsed
(缓存未命中数)/(指令数)很低,约为 0.7%。 Here 有人提到这个数字是检查内存效率的好东西。
另一方面,缓存未命中占缓存引用的百分比非常高(65%!),我认为这可能表明缓存效率方面的执行出现了问题。
perf stat -d
的详细统计数据是:
2711.191150 task-clock # 2.978 CPUs utilized
1,421 context-switches # 0.524 K/sec
50 cpu-migrations # 0.018 K/sec
362,533 page-faults # 0.134 M/sec
8,518,897,738 cycles # 3.142 GHz [40.13%]
6,089,067,266 stalled-cycles-frontend # 71.48% frontend cycles idle [39.76%]
4,419,565,197 stalled-cycles-backend # 51.88% backend cycles idle [39.37%]
7,095,514,317 instructions # 0.83 insns per cycle
# 0.86 stalled cycles per insn [49.66%]
858,812,708 branches # 316.766 M/sec [49.77%]
3,282,725 branch-misses # 0.38% of all branches [50.19%]
1,899,797,603 L1-dcache-loads # 700.724 M/sec [50.66%]
153,927,756 L1-dcache-load-misses # 8.10% of all L1-dcache hits [50.94%]
45,287,408 LLC-loads # 16.704 M/sec [40.70%]
26,011,069 LLC-load-misses # 57.44% of all LL-cache hits [40.45%]
0.910380914 seconds time elapsed
此处前端和后端停滞周期也很高,较低级别的缓存似乎有 57.5% 的高未命中率。
哪个指标最适合这种情况?我在想的一个想法是,在初始图像加载之后,工作负载可能不再需要更多 "touching" LL 缓存(加载一次值,然后完成加载 - 工作负载更多 CPU-bound 比 memory-bound 是一种图像过滤算法)。
我运行安装此机器的机器是 Xeon E5-2680(20M 智能缓存,其中每个内核 256KB L2 缓存,8 个内核)。
您要确保的第一件事是您的机器上运行没有其他计算密集型进程。那是一台服务器 CPU 所以我认为这可能是个问题。
如果您在程序中使用多线程,并且在线程之间分配等量的工作,您可能会对仅在一个 CPU 上收集指标感兴趣。
我建议在优化阶段禁用超线程,因为它会在解释分析指标时造成混淆。 (例如增加在后端花费的#cycles)。此外,如果您将工作分配给 3 个线程,则很有可能 2 个线程将共享一个内核的资源,而第 3 个线程将拥有整个内核 - 而且速度会更快。
Perf 从来都不擅长解释指标。从数量级来看,缓存引用是命中 LLC 的 L2 未命中。如果 LLC 引用/#Instructions 的数量较低,则与 LLC 引用相比,较高的 LLC 未命中数并不总是一件坏事。在您的情况下,您有 0.018,这意味着您的大部分数据都是从 L2 使用的。高 LLC 未命中率意味着您仍然需要从 RAM 中获取数据并将其写回。
关于#Cycles BE 和 FE 绑定,我有点担心这些值,因为它们的总和不等于 100% 和循环总数。您有 8G,但在 FE 中保持 6G 周期,在 BE 中保持 4G 周期。这似乎不太正确。
如果 FE 周期很高,这意味着您在指令缓存中有未命中或错误的分支推测。如果 BE 周期很高,则表示您等待数据。
无论如何,关于你的问题。评估代码性能最相关的指标是 指令/周期 (IPC)。您的 CPU 最多可以执行 4 条指令/周期。你只执行0.8。这意味着资源未得到充分利用,除非您有许多矢量指令。在 IPC 之后,您需要检查分支未命中和 L1 未命中(数据和代码),因为这些会产生最多的惩罚。
最后一个建议:您可能有兴趣试用英特尔的 vTune 放大器。它对指标进行了更好的解释,并指出了代码中可能出现的问题。
我开发了一种代码,可以将大型二维图像(高达 64MPixels)作为输入,并且:
- 对每行应用过滤器
- 转置图像(使用分块以避免大量缓存未命中)
- 对图像的列(现在是行)应用过滤器
- 将过滤后的图像转置回去进行其他计算
虽然它没有改变什么,但为了我的问题的完整性,过滤应用了离散小波变换并且代码是用 C 编写的。
我的最终目标是让这个 运行 尽可能快。通过使用阻塞矩阵转置、矢量化、多线程、编译器友好代码等,我到目前为止的加速超过 10 倍
回答我的问题:我所拥有的代码的最新分析统计数据(使用 perf stat -e
)让我很困扰。
76,321,873 cache-references
8,647,026,694 cycles # 0.000 GHz
7,050,257,995 instructions # 0.82 insns per cycle
49,739,417 cache-misses # 65.171 % of all cache refs
0.910437338 seconds time elapsed
(缓存未命中数)/(指令数)很低,约为 0.7%。 Here 有人提到这个数字是检查内存效率的好东西。
另一方面,缓存未命中占缓存引用的百分比非常高(65%!),我认为这可能表明缓存效率方面的执行出现了问题。
perf stat -d
的详细统计数据是:
2711.191150 task-clock # 2.978 CPUs utilized
1,421 context-switches # 0.524 K/sec
50 cpu-migrations # 0.018 K/sec
362,533 page-faults # 0.134 M/sec
8,518,897,738 cycles # 3.142 GHz [40.13%]
6,089,067,266 stalled-cycles-frontend # 71.48% frontend cycles idle [39.76%]
4,419,565,197 stalled-cycles-backend # 51.88% backend cycles idle [39.37%]
7,095,514,317 instructions # 0.83 insns per cycle
# 0.86 stalled cycles per insn [49.66%]
858,812,708 branches # 316.766 M/sec [49.77%]
3,282,725 branch-misses # 0.38% of all branches [50.19%]
1,899,797,603 L1-dcache-loads # 700.724 M/sec [50.66%]
153,927,756 L1-dcache-load-misses # 8.10% of all L1-dcache hits [50.94%]
45,287,408 LLC-loads # 16.704 M/sec [40.70%]
26,011,069 LLC-load-misses # 57.44% of all LL-cache hits [40.45%]
0.910380914 seconds time elapsed
此处前端和后端停滞周期也很高,较低级别的缓存似乎有 57.5% 的高未命中率。
哪个指标最适合这种情况?我在想的一个想法是,在初始图像加载之后,工作负载可能不再需要更多 "touching" LL 缓存(加载一次值,然后完成加载 - 工作负载更多 CPU-bound 比 memory-bound 是一种图像过滤算法)。
我运行安装此机器的机器是 Xeon E5-2680(20M 智能缓存,其中每个内核 256KB L2 缓存,8 个内核)。
您要确保的第一件事是您的机器上运行没有其他计算密集型进程。那是一台服务器 CPU 所以我认为这可能是个问题。
如果您在程序中使用多线程,并且在线程之间分配等量的工作,您可能会对仅在一个 CPU 上收集指标感兴趣。
我建议在优化阶段禁用超线程,因为它会在解释分析指标时造成混淆。 (例如增加在后端花费的#cycles)。此外,如果您将工作分配给 3 个线程,则很有可能 2 个线程将共享一个内核的资源,而第 3 个线程将拥有整个内核 - 而且速度会更快。
Perf 从来都不擅长解释指标。从数量级来看,缓存引用是命中 LLC 的 L2 未命中。如果 LLC 引用/#Instructions 的数量较低,则与 LLC 引用相比,较高的 LLC 未命中数并不总是一件坏事。在您的情况下,您有 0.018,这意味着您的大部分数据都是从 L2 使用的。高 LLC 未命中率意味着您仍然需要从 RAM 中获取数据并将其写回。
关于#Cycles BE 和 FE 绑定,我有点担心这些值,因为它们的总和不等于 100% 和循环总数。您有 8G,但在 FE 中保持 6G 周期,在 BE 中保持 4G 周期。这似乎不太正确。
如果 FE 周期很高,这意味着您在指令缓存中有未命中或错误的分支推测。如果 BE 周期很高,则表示您等待数据。
无论如何,关于你的问题。评估代码性能最相关的指标是 指令/周期 (IPC)。您的 CPU 最多可以执行 4 条指令/周期。你只执行0.8。这意味着资源未得到充分利用,除非您有许多矢量指令。在 IPC 之后,您需要检查分支未命中和 L1 未命中(数据和代码),因为这些会产生最多的惩罚。
最后一个建议:您可能有兴趣试用英特尔的 vTune 放大器。它对指标进行了更好的解释,并指出了代码中可能出现的问题。