TL;博士
RDTSC
您在和之间观察到的差异REFTSC
是由 TurboBoost P 状态转换引起的。在这些转换过程中,包括固定功能性能计数器在内的大部分内核REF_TSC
都会暂停大约 20000-21000 个周期(8.5us),但会rdtsc
继续以不变的频率运行。rdtsc
可能在一个隔离的电源和时钟域中,因为它非常重要并且因为它记录了类似挂钟的行为。
RDTSC-REFTSC
差异_
这种差异表现为过度计算的RDTSC
趋势REFTSC
。程序运行的时间越长,差异RDTSC-REFTSC
往往越积极。在很长的一段时间内,它可以高达 1%-2% 甚至更高。
当然,自己已经观察到,禁用TurboBoost时,过度计数会消失,使用时可以这样做intel_pstate
:
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
但这并不能肯定地告诉我们 TurboBoost 对这种差异有过错。可能是 TurboBoost 启用的更高 P 状态会耗尽可用的净空,从而导致热节流和停止。
可能的节流?
TurboBoost 是一种动态频率和电压缩放解决方案,可适时利用工作包络(热或电)中的裕量。在可能的情况下,TurboBoost 会将处理器的核心频率和电压按比例提高到超出其标称值,从而以更高的功耗为代价提高性能。
更高的功耗当然会增加核心温度和功耗。最终,将达到某种限制,TurboBoost 将不得不降低性能。
TM1 热节流?
我首先调查了热监控器 1 (TM1) 或 2 (TM2) 的热控制电路 (TCC) 是否会导致热节流。TM1 通过插入 TM 停止时钟周期来降低功耗,这些是记录的导致REFTSC
. 另一方面,TM2 不对时钟进行门控;它只缩放频率。
我进行了修改libpfc()
以使我能够阅读选择的 MSR,特别是IA32_PACKAGE_THERM_STATUS
和IA32_THERM_STATUS
MSR。两者都包含用于各种热条件的只读状态和读写、硬件粘性日志标志:
(IA32_PACKAGE_THERM_STATUS
注册表基本相同)
虽然有时会设置其中一些位(尤其是在阻塞笔记本电脑通风口时!),但它们似乎与RDTSC
过度计数无关,无论热状态如何,这种情况都会可靠地发生。
硬件工作循环?C州居留权?
在 SDM 的其他地方挖掘类似停止时钟的硬件时,我偶然发现了 HDC(硬件占空比),这是一种操作系统可以手动请求 CPU 仅在固定比例的时间内运行的机制;HDC 硬件通过在每 16 个时钟周期运行处理器 1-15 个时钟周期并在该周期的剩余 15-1 个时钟周期强制空闲它来实现这一点。
HDC 提供了非常有用的寄存器,尤其是 MSR:
IA32_THREAD_STALL
:计算由于此逻辑处理器上的强制空闲而停止的周期数。
MSR_CORE_HDC_RESIDENCY
:与上述相同,但对于物理处理器,当该内核的一个或多个逻辑处理器强制空闲时计数周期。
MSR_PKG_HDC_SHALLOW_RESIDENCY
:计算程序包处于 C2 状态并且至少一个逻辑处理器处于强制空闲状态的周期。
MSR_PKG_HDC_DEEP_RESIDENCY
:计算程序包处于更深(精确可配置)C 状态并且至少一个逻辑处理器处于强制空闲状态的周期。
有关详细信息,请参阅英特尔 SDM 第 3 卷第 14 章第14.5.1 节硬件占空比编程接口。
但是我的 i7-4700MQ 2.4 GHz CPU 不支持 HDC,所以这就是 HDC。
其他节流来源?
在英特尔 SDM 中挖掘更多内容,我发现了一个非常非常多汁的 MSR MSR_CORE_PERF_LIMIT_REASONS
:. 该寄存器报告了大量非常有用的状态和粘性日志位:
690H MSR_CORE_PERF_LIMIT_REASONS - 封装 - 处理器内核中的频率削波指示器
- 位
0
:PROCHOT 状态
- 位
1
:热状态
- 位
4
:显卡驱动状态。设置后,由于处理器图形驱动程序覆盖,频率会降低到操作系统请求以下。
- 位
5
:基于自主利用的频率控制状态。设置后,频率会降低到操作系统请求以下,因为处理器检测到利用率很低。
- 位
6
:电压调节器热警报状态。设置后,由于电压调节器的热警报,频率会降低到操作系统请求以下。
- 位
8
:电气设计点状态。设置后,由于电气设计点限制(例如最大电流消耗),频率会降低到操作系统要求以下。
- 位
9
:核心功率限制状态。设置后,由于域级功率限制,频率会降低到操作系统请求以下。
- 位
10
:封装级功率限制 PL1 状态。设置后,由于封装级功率限制 PL1,频率会降低到操作系统请求以下。
- 位
11
:封装级功率限制 PL2 状态。设置后,由于封装级功率限制 PL2,频率会降低到操作系统请求以下。
- 位
12
:最大涡轮限制状态。设置后,由于多核 turbo 限制,频率会降低到操作系统请求以下。
- 位
13
:Turbo 转换衰减状态。设置后,由于 Turbo 转换衰减,频率会降低到操作系统请求以下。这可以防止由于频繁的操作比变化而导致性能下降。
- 位
16
:PROCHOT 日志
- 位
17
:热日志
- 位
20
:图形驱动程序日志
- 位
21
:基于自主利用的频率控制日志
- 位
22
:电压调节器热警报日志
- 位
24
:电气设计点日志
- 位
25
:核心功率限制日志
- 位
26
:封装级功率限制 PL1 日志
- 位
27
:封装级功率限制 PL2 日志
- 位
28
:最大 Turbo 限制日志
- 位
29
:Turbo 转换衰减日志
pfc.ko
现在支持此 MSR,并且演示打印这些日志位中的哪些是活动的。驱动程序在pfc.ko
每次读取时清除粘滞位。
我在打印位时重新运行了您的实验,并且我的 CPU 在非常重的负载(所有 4 个内核/8 个线程都处于活动状态)下报告了几个限制因素,包括电气设计点和核心功率限制。由于我不知道的原因,始终在我的 CPU 上设置Package-Level PL2 和 Max Turbo Limit位。我也偶尔看到Turbo Transition Attenuation。
虽然这些位中没有一个与RDTSC-REFTSC
差异的存在完全相关,但最后一位让我深思。Turbo Transition Attenuation的存在意味着切换 P 状态具有足够大的成本,因此必须通过某种滞后机制对其进行速率限制。当我找不到对这些转换进行计数的 MSR 时,我决定做下一件最好的事情 - 我将使用过度计数的幅度来描述 TurboBoost 转换的性能影响。RDTSC-REFTSC
实验
实验设置如下。在我的 i7-4700MQ CPU、标称速度 2.4GHz 和最大 Turbo Speed 3.4GHz 上,我将离线除 0(引导处理器)和 3(方便的受害者核心,不编号为 0 且不是 0 的逻辑兄弟)之外的所有核心。然后我们会要求intel_pstate
司机给我们一个不低于98%不高于100%的包裹性能;这限制了处理器在第二高和最高 P 状态(3.3 GHz 和 3.4 GHz)之间振荡。我这样做如下:
echo 0 > /sys/devices/system/cpu/cpu1/online
echo 0 > /sys/devices/system/cpu/cpu2/online
echo 0 > /sys/devices/system/cpu/cpu4/online
echo 0 > /sys/devices/system/cpu/cpu5/online
echo 0 > /sys/devices/system/cpu/cpu6/online
echo 0 > /sys/devices/system/cpu/cpu7/online
echo 98 > /sys/devices/system/cpu/intel_pstate/min_perf_pct
echo 100 > /sys/devices/system/cpu/intel_pstate/max_perf_pct
我在以下位置运行了10000 个样本的演示应用程序
1000, 1500, 2500, 4000, 6300,
10000, 15000, 25000, 40000, 63000,
100000, 150000, 250000, 400000, 630000,
1000000, 1500000, 2500000, 4000000, 6300000,
10000000, 15000000, 25000000, 40000000, 63000000
以标称 CPU 频率执行的每次纳秒add_calibration()
(将上面的数字乘以 2.4 以获得 的实际参数add_calibration()
)。
结果
这会产生如下所示的日志(250000 纳秒的情况):
CPU 0, measured CLK_REF_TSC MHz : 2392.56
CPU 0, measured rdtsc MHz : 2392.46
CPU 0, measured add MHz : 3286.30
CPU 0, measured XREF_CLK time (s) : 0.00018200
CPU 0, measured delta time (s) : 0.00018258
CPU 0, measured tsc_delta time (s) : 0.00018200
CPU 0, ratio ref_tsc :ref_xclk : 24.00131868
CPU 0, ratio ref_core:ref_xclk : 33.00071429
CPU 0, ratio rdtsc :ref_xclk : 24.00032967
CPU 0, core CLK cycles in OS : 0
CPU 0, User-OS transitions : 0
CPU 0, rdtsc-reftsc overcount : -18
CPU 0, MSR_IA32_PACKAGE_THERM_STATUS : 000000008819080a
CPU 0, MSR_IA32_PACKAGE_THERM_INTERRUPT: 0000000000000003
CPU 0, MSR_CORE_PERF_LIMIT_REASONS : 0000000018001000
PROCHOT
Thermal
Graphics Driver
Autonomous Utilization-Based Frequency Control
Voltage Regulator Thermal Alert
Electrical Design Point (e.g. Current)
Core Power Limiting
Package-Level PL1 Power Limiting
* Package-Level PL2 Power Limiting
* Max Turbo Limit (Multi-Core Turbo)
Turbo Transition Attenuation
CPU 0, measured CLK_REF_TSC MHz : 2392.63
CPU 0, measured rdtsc MHz : 2392.62
CPU 0, measured add MHz : 3288.03
CPU 0, measured XREF_CLK time (s) : 0.00018192
CPU 0, measured delta time (s) : 0.00018248
CPU 0, measured tsc_delta time (s) : 0.00018192
CPU 0, ratio ref_tsc :ref_xclk : 24.00000000
CPU 0, ratio ref_core:ref_xclk : 32.99983509
CPU 0, ratio rdtsc :ref_xclk : 23.99989006
CPU 0, core CLK cycles in OS : 0
CPU 0, User-OS transitions : 0
CPU 0, rdtsc-reftsc overcount : -2
CPU 0, MSR_IA32_PACKAGE_THERM_STATUS : 000000008819080a
CPU 0, MSR_IA32_PACKAGE_THERM_INTERRUPT: 0000000000000003
CPU 0, MSR_CORE_PERF_LIMIT_REASONS : 0000000018001000
PROCHOT
Thermal
Graphics Driver
Autonomous Utilization-Based Frequency Control
Voltage Regulator Thermal Alert
Electrical Design Point (e.g. Current)
Core Power Limiting
Package-Level PL1 Power Limiting
* Package-Level PL2 Power Limiting
* Max Turbo Limit (Multi-Core Turbo)
Turbo Transition Attenuation
CPU 0, measured CLK_REF_TSC MHz : 2284.69
CPU 0, measured rdtsc MHz : 2392.63
CPU 0, measured add MHz : 3151.99
CPU 0, measured XREF_CLK time (s) : 0.00018121
CPU 0, measured delta time (s) : 0.00019036
CPU 0, measured tsc_delta time (s) : 0.00018977
CPU 0, ratio ref_tsc :ref_xclk : 24.00000000
CPU 0, ratio ref_core:ref_xclk : 33.38540919
CPU 0, ratio rdtsc :ref_xclk : 25.13393301
CPU 0, core CLK cycles in OS : 0
CPU 0, User-OS transitions : 0
CPU 0, rdtsc-reftsc overcount : 20548
CPU 0, MSR_IA32_PACKAGE_THERM_STATUS : 000000008819080a
CPU 0, MSR_IA32_PACKAGE_THERM_INTERRUPT: 0000000000000003
CPU 0, MSR_CORE_PERF_LIMIT_REASONS : 0000000018000000
PROCHOT
Thermal
Graphics Driver
Autonomous Utilization-Based Frequency Control
Voltage Regulator Thermal Alert
Electrical Design Point (e.g. Current)
Core Power Limiting
Package-Level PL1 Power Limiting
* Package-Level PL2 Power Limiting
* Max Turbo Limit (Multi-Core Turbo)
Turbo Transition Attenuation
CPU 0, measured CLK_REF_TSC MHz : 2392.46
CPU 0, measured rdtsc MHz : 2392.45
CPU 0, measured add MHz : 3287.80
CPU 0, measured XREF_CLK time (s) : 0.00018192
CPU 0, measured delta time (s) : 0.00018249
CPU 0, measured tsc_delta time (s) : 0.00018192
CPU 0, ratio ref_tsc :ref_xclk : 24.00000000
CPU 0, ratio ref_core:ref_xclk : 32.99978012
CPU 0, ratio rdtsc :ref_xclk : 23.99989006
CPU 0, core CLK cycles in OS : 0
CPU 0, User-OS transitions : 0
CPU 0, rdtsc-reftsc overcount : -2
CPU 0, MSR_IA32_PACKAGE_THERM_STATUS : 000000008819080a
CPU 0, MSR_IA32_PACKAGE_THERM_INTERRUPT: 0000000000000003
CPU 0, MSR_CORE_PERF_LIMIT_REASONS : 0000000018001000
PROCHOT
Thermal
Graphics Driver
Autonomous Utilization-Based Frequency Control
Voltage Regulator Thermal Alert
Electrical Design Point (e.g. Current)
Core Power Limiting
Package-Level PL1 Power Limiting
* Package-Level PL2 Power Limiting
* Max Turbo Limit (Multi-Core Turbo)
Turbo Transition Attenuation
我对日志做了一些观察,但有一个很突出:
对于 nanos < ~250000,RDTSC 的过度计数可以忽略不计。对于 nanos > ~250000,可以可靠地观察到刚好超过 20000 个时钟周期的过度计数时钟周期量。但它们不是由于用户-操作系统转换。
这是一个视觉图:
饱和蓝点:0 标准差(接近平均值)
饱和红点:+3 标准差(高于平均值)
饱和绿点:-3 标准差(低于平均值)
在大约 250000 纳秒的持续递减之前、期间和之后存在显着差异。
纳米 < 250000
在阈值之前,CSV 日志如下所示:
24.00,33.00,24.00,-14,0,0
24.00,33.00,24.00,-20,0,0
24.00,33.00,24.00,-4,3639,1
24.00,33.00,24.00,-20,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,-14,0,0
24.00,33.00,24.00,-14,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,-44,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,-14,0,0
24.00,33.00,24.00,-20,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,-20,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,12,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,10,0,0
24.00,33.00,24.00,-20,0,0
24.00,33.00,24.00,32,3171,1
24.00,33.00,24.00,-20,0,0
24.00,33.00,24.00,10,0,0
表明 TurboBoost 比率完全稳定在 33 倍,与24 倍(100 MHz)的速率RDTSC
同步计数,可忽略不计的过度计数,通常在内核中花费 0 个周期,因此 0 个转换到内核。内核中断服务大约需要 3000 个参考周期。REFTSC
REF_XCLK
纳米 == 250000
在临界阈值处,日志包含 20000 个循环超计数的块,并且超计数与 33x 和 34x 之间的非整数估计乘数值非常相关:
24.00,33.00,24.00,-2,0,0
24.00,33.00,24.00,-2,0,0
24.00,33.00,24.00,2,0,0
24.00,33.00,24.00,22,0,0
24.00,33.00,24.00,-2,0,0
24.00,33.00,24.00,-2,0,0
24.00,33.00,24.00,-2,0,0
24.00,33.05,25.11,20396,0,0
24.00,33.38,25.12,20212,0,0
24.00,33.39,25.12,20308,0,0
24.00,33.42,25.12,20296,0,0
24.00,33.43,25.11,20158,0,0
24.00,33.43,25.11,20178,0,0
24.00,33.00,24.00,-4,0,0
24.00,33.00,24.00,20,3920,1
24.00,33.00,24.00,-2,0,0
24.00,33.00,24.00,-4,0,0
24.00,33.44,25.13,20396,0,0
24.00,33.46,25.11,20156,0,0
24.00,33.46,25.12,20268,0,0
24.00,33.41,25.12,20322,0,0
24.00,33.40,25.11,20216,0,0
24.00,33.46,25.12,20168,0,0
24.00,33.00,24.00,-2,0,0
24.00,33.00,24.00,-2,0,0
24.00,33.00,24.00,-2,0,0
24.00,33.00,24.00,22,0,0
纳米 > 250000
从 3.3 GHz 到 3.4 GHz 的 TurboBoost 现在可以可靠地发生。随着纳米的增加,日志中充满了大约 20000 周期量子的整数倍。最终有太多的 nano 以至于 Linux 调度程序中断成为永久固定装置,但是使用性能计数器很容易检测到抢占,其效果与 TurboBoost 停止完全不同。
24.00,33.75,24.45,20166,0,0
24.00,33.78,24.45,20302,0,0
24.00,33.78,24.45,20202,0,0
24.00,33.68,24.91,41082,0,0
24.00,33.31,24.90,40998,0,0
24.00,33.70,25.30,58986,3668,1
24.00,33.74,24.42,18798,0,0
24.00,33.74,24.45,20172,0,0
24.00,33.77,24.45,20156,0,0
24.00,33.78,24.45,20258,0,0
24.00,33.78,24.45,20240,0,0
24.00,33.77,24.42,18826,0,0
24.00,33.75,24.45,20372,0,0
24.00,33.76,24.42,18798,4081,1
24.00,33.74,24.41,18460,0,0
24.00,33.75,24.45,20234,0,0
24.00,33.77,24.45,20284,0,0
24.00,33.78,24.45,20150,0,0
24.00,33.78,24.45,20314,0,0
24.00,33.78,24.42,18766,0,0
24.00,33.71,25.36,61608,0,0
24.00,33.76,24.45,20336,0,0
24.00,33.78,24.45,20234,0,0
24.00,33.78,24.45,20210,0,0
24.00,33.78,24.45,20210,0,0
24.00,33.00,24.00,-10,0,0
24.00,33.00,24.00,4,0,0
24.00,33.00,24.00,18,0,0
24.00,33.00,24.00,2,4132,1
24.00,33.00,24.00,44,0,0
结论
TurboBoost 机械是造成RDTSC-REFTSC
. 此差异可用于确定从 3.3 GHz 到 3.4 GHz 的 TurboBoost 状态转换大约需要 20500 个参考时钟周期(8.5us),并且在进入 后不迟于大约 250000 ns(250us;600000 个参考时钟周期)触发add_reference()
,当处理器决定工作负载足够强烈以至于值得进行频率-电压缩放时。
未来的工作
需要做更多的研究来确定转换成本如何随频率变化,以及选择电源状态的硬件是否可以调整。我特别感兴趣的是“Turbo Attenuation Units”,我在网络的远端看到了一些提示。也许 Turbo 硬件有一个可配置的时间窗口?目前,决定时间与转换时间的比率为 30:1 (600us:20us)。可以调吗?