kou*_*iou 5 optimization performance caching computer-architecture perf
我开发了一个代码,可以输入一个大的2-D图像(最高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
Run Code Online (Sandbox Code Playgroud)
(缓存未命中数)/(#指令)低约0.7%.这里提到这个数字是检查内存效率的好事.
另一方面,高速缓存未命中高速缓存引用的百分比非常高(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
Run Code Online (Sandbox Code Playgroud)
这里前端和后端停滞的周期也很高,较低级别的缓存似乎遭受57.5%的高失误率.
哪种指标最适合此方案?我想到的一个想法是,在初始图像加载之后,工作负载不再需要进一步"触摸"LL缓存(加载值一次,之后就完成了 - 工作负载比CPU更多 - 内存绑定是一种图像过滤算法).
我正在运行的机器是Xeon E5-2680(20M的智能缓存,其中每个核心有256KB二级缓存,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 Amplifier。它对指标提供了更好的解释,并指出代码中的最终问题。
| 归档时间: |
|
| 查看次数: |
3041 次 |
| 最近记录: |