首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >树莓PI基准时间与std::chrono::steady_clock异常

树莓PI基准时间与std::chrono::steady_clock异常
EN

Stack Overflow用户
提问于 2022-09-30 14:28:32
回答 1查看 118关注 0票数 1

我正在尝试用std::chrono::steady_clock在Raspberry Pi 4上测试一段DSP代码,但是我得到的结果很奇怪。因为GNU分析工具不适用于Raspberry Pi,所以我不得不用基准来评估代码优化,所以这是一件很重要的事情。

什么会导致基准程序的执行之间性能相差10%,而当相同的测试在同一程序的执行中多次运行时,会保持+/- 1%的一致性?

对于~6秒基准测试的结果变化约为10%.但奇怪的是,对于基准测试的特定执行而言,差异似乎很棘手。每次运行程序时,我都会连续运行三次基准测试,得到的结果大致相同-- +/- 1%。但是,当我重新运行程序时,这三个基准测试的结果与上一次运行相比变化了+/- 10%,但是新运行中的三个结果都是+/- 1%。

例如:

代码语言:javascript
复制
Run 1:
9:21:37. Performance: 0.0912333 x realtime
9:21:42. Performance: 0.0910667 x realtime
9:21:47. Performance: 0.0910667 x realtime

Run 2:
9:20:15. Performance: 0.106667 x realtime
9:20:21. Performance: 0.1062 x realtime
9:20:28. Performance: 0.106117 x realtime

结果在每一次跑步的这两个极端之间随机变化。但这里的奇怪之处是,每次运行程序时,三个测试之间的结果都与+/- 1%一致。

我是一个有经验的程序员,所以我知道基准测试会有所不同。但是对于我想做的事情,10%的方差是不可行的。我无法给出一个合理的理论来解释为什么从调用到调用的差异会发生变化。

测试中的代码是一种机器学习算法(LSTM->稠密),它使用手工优化的neon本质来生成实时音频.执行的大部分(~90%)是使用手工优化的neon本质的矩阵和向量算法。数据占用约13 is (适合在L1 d-缓存中使用)。代码占用是未知的,但可能不适合L1 i-缓存。大部分代码管道漂亮,所以代码可能运行接近L1缓存带宽限制。到目前为止,优化已使实时性从~0.18倍提高到0.093倍。我认为可能还有另外15%的改进,但时机不准确在这一点上受到了阻碍。测试中的代码被执行了三次,占用了0.3x的实时时间,因此进一步的优化实际上是至关重要的。

检查过的东西:

  • 不是霓虹灯对齐问题。所有矩阵、矩阵行和向量都是16字节对齐的(与调试编译中的断言检查)。

  • 不是CPU频率问题。CPU缩放调控器已设置为performance,所有CPU在1.8Ghz.

上运行。

  • 我不认为它与进程之间的缓存竞争有关。HTOP表明:当VNC连接时,大约6%的CPU在空闲时使用;当通过ssh连接时,约有0.3% (wifi请求)使用CPU。当通过SSH.

连接时,模式没有明显的变化。

  • --我不认为这取决于代码运行在哪个CPU核心上--尽管我只能使用HTOP来确定代码在特定运行中运行的核心,而这并不是完全确定的。测试运行似乎偶尔会转移到不同的CPU核心,但在大多数情况下,在每次运行3次测试期间,它们似乎运行在一个随机选择的核心上。

  • ,我不认为是热节流。CPU温度是一个非常温和的47摄氏度。我不认为覆盆子pI4s热节流阀,直到他们到达80C.

  • 向量操作依赖于GCC编译器的自动矢量化,该编译器已经正确地注释了限制的声明,并被证实产生了最优的霓虹灯矢量化(指令调度比我用neon 所能产生的更好)。

  • 不是定时器解决问题。对std::chrono::steady_clock::now()的连续调用会产生37到56 and的增量。

  • 没有选择时钟的问题。steady_clock、system_clock和high_resolution_clock都表现出相同的行为。

验证cpu频率:

代码语言:javascript
复制
$ cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 
performance
performance
performance
performance

$ cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq 
1800000
1800000
1800000
1800000

我不知道你也许能帮上忙的事情:

  • 如何在覆盆子Pi上实现std::chrono::steady_clock。它是基于CPU时钟计数器吗?任何细节appreciated.

热节流是否反映在/sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq.中的

  • 我想是的,但我不确定。--

  • 我显然错过了一些重要的事情。--

技术细节:

GNU/Linux

  • gcc
  • Raspberry Pi 4b 8GB
  • raspberrypi 5.15.61-v8+ #1579 SMP抢占星期五8月26日11:16:44 BST 2022 aarch64版本10.2.1 20210110 (Debian 10.2.1-6)
  • Tests在catch2测试框架下运行。

)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-05 17:29:16

最后找出了问题的根源。这个问题似乎是对L1缓存内容的非常温和的竞争,大概是来自某个后台系统过程。

性能计数器表现出与基准测试相同的奇怪行为:每次启动测试程序时,连续运行3次,基准测试结果的方差为1%;但启动到启动的结果相差约10%。

奇怪的是,测试运行之间的性能差异是一致的,并且持续了几秒钟。但是,考虑到L1缓存的干扰有多小,很难猜测有一百多个正在运行的系统进程会干扰基准测试,为什么会出现这种非常不幸的模式,特别是因为它们可以在任何调度程序优先级下运行。

性能计数器测量的结果说明了这个问题:每迭代2,995条指令,平均有30个额外的L1数据缓存丢失,占基准测试结果的10%的方差。令人惊讶的是。

我无法猜测什么样的系统进程会以在18秒内保持一致的速率污染L1数据缓存,但在较大的时间范围内会有所不同。

好消息是:测试中的代码非常接近最优。(一个具有两个实质性乘法和大量向量化ArcTan和Sigmoid函数调用的LSTM单元),它设法使用75%以上的可用缓存内存带宽,并在每个时钟周期发出几乎两个指令。哇哦!

试验数据

测试代码的每次迭代平均性能计数器度量。该程序的每次启动运行三次~6秒基准。

良好的测试程序运行:

代码语言:javascript
复制
CpuClk      :           1,694
L1D Access  :           1,244
L1D Miss    :               6
L1I Miss    :               0
Instructions:           2,995
L2 Access   :              12
L2 Miss     :               0

---
CpuClk      :           1,694
L1D Access  :           1,244
L1D Miss    :               6
L1I Miss    :               0
Instructions:           2,995
L2 Access   :              12
L2 Miss     :               0

---
CpuClk      :           1,693
L1D Access  :           1,244
L1D Miss    :               6
L1I Miss    :               0
Instructions:           2,995
L2 Access   :              12
L2 Miss     :               0

糟糕的运行:

代码语言:javascript
复制
CpuClk      :           1,797
L1D Access  :           1,244
L1D Miss    :              37
L1I Miss    :               0
Instructions:           2,995
L2 Access   :              78
L2 Miss     :               0

---
CpuClk      :           1,794
L1D Access  :           1,244
L1D Miss    :              37
L1I Miss    :               0
Instructions:           2,995
L2 Access   :              78
L2 Miss     :               0

---
CpuClk      :           1,797
L1D Access  :           1,244
L1D Miss    :              37
L1I Miss    :               0
Instructions:           2,995
L2 Access   :              78
L2 Miss     :               0
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73910282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档