【问题标题】:Perf stat number of cycles and frequency scalingPerf stat 周期数和频率缩放
【发布时间】:2016-07-18 18:15:21
【问题描述】:

我一直在 odroid-xu3 上使用 perf statcpufreq-set 进行小型实验,这是一个带有 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 次实验的平均值,因此相同频率的变化非常低(

【问题讨论】:

  • 可能需要对该处理器的体系结构有更多了解。这可能有很多原因(内存——有多大的矩阵,有多大的内存和缓存可用,......)。内核或其他运行的应用程序可能存在开销。从这个描述真的很难说。
  • 在相同频率的运行之间您看到多少变化?
  • 首先,您如何知道您的程序执行是线性的和 100% 确定性的?如果您有一个带有上下文切换的操作系统,这似乎不太可能。如果你有中断,同样的事情。
  • 好的,但是线性反对什么?它应该是 100% 确定性的,因为它是 BLAS lvl3 内核,没有数据依赖行为。它只是在处理数据。所以我想如果与频率成线性关系,那么应该是。我当然有上下文切换和中断,但我没想到会有太多开销,因为除了这个之外机器基本上什么都不做。
  • Emilien,您确实计算了 CPU 周期。 CPU 将在计算某些东西时以及当它停止并等待数据(来自缓存,来自内存)时循环。不仅要检查周期,还要检查应该更稳定的指令计数器(如果此性能计数器是为您的 CPU 实现的),还要将内核模式排除在使用 :u 后缀:perf stat -e cycles:u,instructions:u,task-clock:u ./program 的计数之外。当您对 CPU Freq 进行降频时,您的内存控制器和内存时序可能会发生变化;内存的刷新时间不是从频率计算的,而是从毫秒计算的(比如在 64 毫秒内完全刷新)。

标签: linux embedded perf energy openblas


【解决方案1】:

CPU 周期不仅用于计算,还用于等待内存中的数据。 (是的,GEMM 是 BLAS3,在 Roofline model scale 上具有非常好的算术强度和少量的内存读/写,但仍然存在内存访问,并且它们的延迟与 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) 时序中,大多数时序将相同(或接近),但有一个会影响您的代码周期:memory refresh timing - DRAM 内存仅在短时间内保留数据(电荷从数据单元),例如每 32 微秒 (ms) 或 64 ms 完全刷新一次(这会随着高温而变化,通常有两个值 - 低温和高温)。 使用完整的数据库刷新命令,它将在 时间 的某些部分无法访问,例如 2% 或 5%(我没有确切的值)。

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

因此,有一些非线性元素具有不同的贡献(一些是负数,另一些是低频率周期的正数):

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

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

【讨论】:

    猜你喜欢
    • 2013-11-14
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 2014-04-05
    • 2018-07-24
    • 2013-10-26
    • 1970-01-01
    • 2015-05-16
    相关资源
    最近更新 更多