【发布时间】:2015-05-16 18:35:39
【问题描述】:
我开发了一个代码,该代码将大型二维图像(高达 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
(# of cache-misses)/(# instructions) 很低,约为 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% 的高未命中率。
哪个指标最适合这种情况?我在想的一个想法是,工作负载可能不再需要在初始图像加载后进一步“接触”LL缓存(加载一次值,然后完成 - 工作负载比 CPU 更受限制) memory-bound 是一种图像过滤算法)。
我运行它的机器是 Xeon E5-2680(20M 智能缓存,其中每个核心 256KB 二级缓存,8 个核心)。
【问题讨论】:
-
koukouviou,
perf stat -d可能不准确,每次运行 4-5 个事件重新运行几次会很有用,perf stat -e L1-dcache-loads,L1-dcache-load-misses,LLC-loads,LLC-loads-misses。如果您的阶段可以分开,您可以测量每个阶段以找出哪个阶段产生未命中。或者您可以运行perf record -e cache-misses来获取丢失最多的代码的配置文件(正如您链接的"Here" 中所建议的那样)。 -
@osgx 我已经完成了你提到的测试,但这篇文章已经很长了,所以我尽量简短。尽管统计数据发生了一些变化,但在高缓存未命中率方面仍保持统计相似性。我已经运行 perf record/report/annotate 并且未命中主要归因于 kernel-kallsyms,但我不知道该怎么做...
-
koukouviou,您可以使用仅限于用户空间的所有事件重新运行您的统计数据:
perf stat -e event1:u,event2:u,...并与发布的结果进行比较(默认情况下,用户和内核都被测量)。 kernel-kallsyms 表示内核空间中的某些函数发生了此事件...此处列出了一些可能的未知/未解决符号问题:brendangregg.com/blog/2014-06-22/perf-cpu-sample.html。我不能给你关于指标的建议......
标签: performance caching optimization computer-architecture perf