Linux 性能统计周期数和频率缩放

Linux 性能统计周期数和频率缩放,linux,embedded,perf,energy,openblas,Linux,Embedded,Perf,Energy,Openblas,我一直在使用odroid-xu3上的perf stat和cpufreq set进行小型实验,odroid-xu3是一种带有Exynos芯片(A7和A15 ARM内核的异构处理器)的嵌入式设备。我使用BLAS lvl3基准测试来运行我的实验,并使用taskset实用程序将任务固定到A15核心。我还仔细检查了它是否是单线程实现 希望在高频或低频运行时,周期数应该相同,但我可以看到一个小的变化,例如在400MHz、1000MHz和1600MHz下分别运行GEMM内核(矩阵乘法,100次运行),我得到以

我一直在使用odroid-xu3上的
perf stat
cpufreq set
进行小型实验,odroid-xu3是一种带有Exynos芯片(A7和A15 ARM内核的异构处理器)的嵌入式设备。我使用BLAS lvl3基准测试来运行我的实验,并使用
taskset
实用程序将任务固定到A15核心。我还仔细检查了它是否是单线程实现

希望在高频或低频运行时,周期数应该相同,但我可以看到一个小的变化,例如在400MHz、1000MHz和1600MHz下分别运行GEMM内核(矩阵乘法,100次运行),我得到以下结果:

7166620830 cycles
17.923790714 seconds time elapsed

7235173436 cycles
7.237463382 seconds time elapsed

7428037080 cycles
4.643897351 seconds time elapsed
您可以看到,即使持续时间与频率也不是真正的线性关系(这至少与测量的周期数一致…)。一个假设是任务有点内存限制,但我对单精度实现有类似的结果。。。你知道这是什么原因吗


编辑:矩阵有400个样本,我使用环境变量OPENBLAS_LOOP(OPENBLAS基准)运行100次。我试图避免其他应用程序运行,我看不出有0%的负载,但已经接近。你建议我停止做一些特别的事情吗?由于这已经是100多个实验的平均值,相同频率下的变化非常低(CPU周期不仅用于计算,而且用于等待内存中的数据。(是的,GEMM是BLAS3,具有非常好的运算强度和较低的内存读/写量,但仍然存在内存访问,它们的延迟与CPU频率不是线性的。)

试着不仅检查CPU周期,还要检查指令计数器,这应该更稳定(如果这个性能计数器是为您的CPU实现的),还要排除内核模式(它可能有一些周期性的任务,每100 Hz或300 Hz一次,就像调度程序一样)使用
:u
后缀进行计数:

perf stat -e cycles:u,instructions:u,task-clock:u ./program
(还要尝试查找为核心实现的一些缓存未命中事件或内存访问事件,也要检查核心文档中的原始编码,并使用
-e rHHHH
查找到的十六进制代码)

当您更改CPU时钟频率时,您可能(也可能不)会影响内存控制器/内存总线频率(具体取决于您的SoC和引导配置)。DRAM内存(可能是“exynos 5422”SoC中的LPDDR3)有许多计时是在内存总线频率中计算的,但实际上它们是从实际内存数据库频率和延迟中计算出来的

大多数计时在绝对(ns)计时中是相同(或接近)的,但有一个计时可能会影响代码周期:-DRAM内存只保留短时间的数据(数据单元的电荷泄漏),例如每32微秒(ms)或64毫秒完全刷新一次(这随高温而变化,通常有两个值-低温和高温)。 使用“完全数据库刷新”命令,在某些时间内它将无法访问,例如2%或5%(我没有确切的值)

更改CPU频率时,不更改刷新频率(数据应始终稳定,并按照内存芯片数据表的要求进行刷新)。但使用400 MHz CPU时,您的计算时间较长,刷新次数较多;使用1600 MHz时,计算时间较短,刷新次数较少。其他影响-某些内存请求可能会暂停,等待刷新结束

因此,存在一些具有不同贡献的非线性元素(对于低频周期,一些为负,另一些为正):

  • CPU频率和DRAM刷新(绝对时间要求)显然不是线性效应
  • CPU频率和Linux内核周期性任务(它们计划每秒运行几次,而不是每十亿个CPU周期)
  • 实际数据访问()以ns为单位测量(但设置和报告以内存总线周期为单位),1600 MHz CPU可能有100个周期从内存中获取第一个字节,但400 MHz CPU可能有60个周期从内存中获取第一个字节

最后一个效果在您的结果中看起来是最显著的-低MHz的低周期,高MHz的高周期。使用高频CPU可能会暂停更多的周期,以等待从内存到预充电/激活行/选择列的几十ns。使用低频率时,相同ns的内存延迟将转换为低数量的慢速CPU周期。

CPU周期不仅用于计算,也用于等待来自内存的数据。(是的,GEMM是BLAS3,在内存上具有非常好的算术强度和较低的内存读/写量,但仍然存在内存访问,它们的延迟与CPU频率不是线性的。)

试着不仅检查CPU周期,还要检查指令计数器,这应该更稳定(如果这个性能计数器是为您的CPU实现的),还要排除内核模式(它可能有一些周期性的任务,每100 Hz或300 Hz一次,就像调度程序一样)使用
:u
后缀进行计数:

perf stat -e cycles:u,instructions:u,task-clock:u ./program
(还要尝试查找为核心实现的一些缓存未命中事件或内存访问事件,也要检查核心文档中的原始编码,并使用
-e rHHHH
查找到的十六进制代码)

当您更改CPU时钟频率时,您可能(也可能不)会影响内存控制器/内存总线频率(具体取决于您的SoC和引导配置)。DRAM内存(可能是“exynos 5422”SoC中的LPDDR3)有许多计时是在内存总线频率中计算的,但实际上它们是从实际内存数据库频率和延迟中计算出来的

大多数计时在绝对(ns)计时中是相同(或接近)的,但有一个计时可能会影响代码周期:-DRAM内存只保留短时间的数据(数据单元的电荷泄漏),例如每32微秒(ms)或64毫秒完全刷新一次(这随高温而变化,通常有两个值-低温和高温)。 使用完整的数据库刷新命令,它将