在最近的CPU上(至少是过去十年左右),Intel提供了三种固定功能硬件性能计数器,此外还有各种可配置的性能计数器。三个固定柜台是:
INST_RETIRED.ANY
CPU_CLK_UNHALTED.THREAD
CPU_CLK_UNHALTED.REF_TSC
第一个计算退役的指令,第二个计算实际循环的数量,最后一个计算我们感兴趣的。《英特尔软件开发人员手册》第3卷的描述如下:
当内核不处于停止状态和TM停止时钟状态时,此事件以TSC速率计算参考周期数。内核在运行HLT指令或MWAIT指令时进入halt状态。该事件不受核心频率变化(例如,P状态)的影响,而是以与时间戳计数器相同的频率计数。此事件可以近似地表示内核未处于停止状态和TM停止时钟状态时所经过的时间。
for (int i = 0; i < 100; i++) {
PFC_CNT cnt[7] = {};
int64_t start = nanos();
PFCSTART(cnt);
int64_t tsc =__rdtsc();
busy_loop(CALIBRATION_LOOPS);
PFCEND(cnt);
int64_t tsc_delta = __rdtsc() - tsc;
int64_t nanos_delta = nanos() - start;
printf(CPU_W "d" REF_W ".2f" TSC_W ".2f" MHZ_W ".2f" RAT_W ".6f\n",
sched_getcpu(),
1000.0 * cnt[PFC_FIXEDCNT_CPU_CLK_REF_TSC] / nanos_delta,
1000.0 * tsc_delta / nanos_delta,
1000.0 * CALIBRATION_LOOPS / nanos_delta,
1.0 * cnt[PFC_FIXEDCNT_CPU_CLK_REF_TSC]/tsc_delta);
}
void busy_loop(uint64_t iters) {
volatile int sink;
do {
sink = 0;
} while (--iters > 0);
(void)sink;
}
int64_t nanos() {
auto t = std::chrono::high_resolution_clock::now();
return std::chrono::time_point_cast<std::chrono::nanoseconds>(t).time_since_epoch().count();
}
是的,我没有发出CPUID
,事情也没有以精确的方式交织,但是校准循环是一整秒钟,所以这种纳秒级的问题只是被稀释到或多或少没有什么。
启用涡轮增压后,在我的i7-6700HQ Skylake CPU上典型运行的前几个结果如下:
CPU# REF_TSC rdtsc Eff Mhz Ratio
0 2392.05 2591.76 2981.30 0.922946
0 2381.74 2591.79 3032.86 0.918955
0 2399.12 2591.79 3032.50 0.925660
0 2385.04 2591.79 3010.58 0.920230
0 2378.39 2591.79 3010.21 0.917663
0 2355.84 2591.77 2928.96 0.908970
0 2364.99 2591.79 2942.32 0.912492
0 2339.64 2591.77 2935.36 0.902720
0 2366.43 2591.79 3022.08 0.913049
0 2401.93 2591.79 3023.52 0.926747
0 2452.87 2591.78 3070.91 0.946400
0 2350.06 2591.79 2961.93 0.906733
0 2340.44 2591.79 2897.58 0.903020
0 2403.22 2591.79 2944.77 0.927246
0 2394.10 2591.79 3059.58 0.923723
0 2359.69 2591.78 2957.79 0.910449
0 2353.33 2591.79 2916.39 0.907992
0 2339.58 2591.79 2951.62 0.902690
0 2395.82 2591.79 3017.59 0.924389
0 2353.47 2591.79 2937.82 0.908047
这里,ref_tsc
是上述固定的TSC性能计数器,rdtsc
是rdtsc
指令的结果。eff MHz
是在该间隔内有效计算的真实CPU频率,主要是出于好奇心的考虑,也是为了快速确认turbo正在发挥多大作用。ratio
是ref_tsc
和rdtsc
列的比率。我希望这个值非常接近1,但在实践中,我们看到它在0.90到0.92之间徘徊,差异很大(我在其他运行中看到它低至0.8)。
从图形上看,它类似于2:
RDSTC
调用返回几乎精确的结果1,而PMU TSC计数器到处都是,有时几乎低至2300 MHz。
然而,如果我关闭turbo,结果会更加一致:
CPU# REF_TSC rdtsc Eff Mhz Ratio
0 2592.26 2592.25 2588.30 1.000000
0 2592.26 2592.26 2591.11 1.000000
0 2592.26 2592.26 2590.40 1.000000
0 2592.25 2592.25 2590.43 1.000000
0 2592.26 2592.26 2590.75 1.000000
0 2592.26 2592.26 2590.05 1.000000
0 2592.25 2592.25 2590.04 1.000000
0 2592.24 2592.24 2590.86 1.000000
0 2592.25 2592.25 2590.35 1.000000
0 2592.25 2592.25 2591.32 1.000000
0 2592.25 2592.25 2590.63 1.000000
0 2592.25 2592.25 2590.87 1.000000
0 2592.25 2592.25 2590.77 1.000000
0 2592.25 2592.25 2590.64 1.000000
0 2592.24 2592.24 2590.30 1.000000
0 2592.23 2592.23 2589.64 1.000000
0 2592.23 2592.23 2590.83 1.000000
0 2592.23 2592.23 2590.49 1.000000
0 2592.23 2592.23 2590.78 1.000000
0 2592.23 2592.23 2590.84 1.000000
0 2592.22 2592.22 2588.80 1.000000
1事实上,有一段时间,我确实得到了精确到小数点后两位的结果:2591.97MHz
-一次又一次迭代。然后发生了一些变化,我不确定是什么,在RDSTC
结果中有大约0.1%的小变化。一种可能是渐进式时钟调整,由Linux计时子系统进行,使本地crystal导出的时间与NTPD
确定的时间一致。也许,这只是一个晶体漂移--上面的最后一张图显示了rdtsc
每秒测量的周期稳步增加。
2这些图与文本中显示的值不对应,因为我不会在每次更改文本输出格式时更新这些图。然而,在每次运行中,定性行为本质上是相同的。
您在rdtsc
和reftsc
之间观察到的差异是由于TurboBoost p态转换造成的。在这些转换期间,大部分核心(包括固定函数性能计数器ref_tsc
)将停止大约20000-21000个周期(8.5us),但rdtsc
将以其不变的频率继续。rdtsc
可能处于一个独立的电源和时钟域中,因为它非常重要,而且它的行为类似于Wallclock。
这种差异表现为rdtsc
超支reftsc
的趋势。程序运行的时间越长,rdtsc-reftsc
的差异越大。在很长一段时间内,它可以高达1%-2%,甚至更高。
当然,您已经观察到,当禁用TurboBoost时,过计数会消失,使用intel_pstate
,可以如下所示:
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
TurboBoost是一种动态的频率和电压缩放解决方案,可以适时地利用工作包络(热或电)中的净空。在可能的情况下,TurboBoost会将处理器的核心频率和电压扩大到超出其标称值,从而以更高的功耗为代价来提高性能。
更高的功耗当然会增加核心温度和功耗。最终,某种极限将被击中,涡轮增压将不得不曲柄降低性能。
我首先调查热监视器1(TM1)或2(TM2)的热控制电路(TCC)是否导致热节流。TM1通过插入TM停止时钟周期来降低功耗,这些是导致reftsc
停止的条件之一。TM2,另一方面,不门时钟;它只调节频率。
IA32_Thread_Stall
:计算由于该逻辑处理器上强制空闲而停顿的循环数。msr_core_hdc_residency
:与上面相同,但是对于物理处理器,当该内核的一个或多个逻辑处理器强制空闲时计算周期。MSR_PKG_HDC_SHALLOW_RESTESENCY
:计算包处于C2状态且至少有一个逻辑处理器处于强制空闲状态的周期。MSR_PKG_HDC_Deep_Residency
:计算包处于更深(精确地说是可配置的)C状态并且至少有一个逻辑处理器处于强制空闲状态的周期。有关详细信息,请参阅Intel SDM第3卷第14章§14.5.1硬件占空比循环编程接口。
但是我的i7-4700MQ 2.4GHz CPU不支持HDC,所以这就是HDC。
0
:PROCHOT状态1
:热状态4
:图形驱动程序状态。设置后,由于处理器图形驱动程序重写,频率会降低到低于操作系统请求。5
:基于自主使用的频率控制状态。设置后,频率降低到低于操作系统请求,因为处理器检测到利用率很低。6
:电压调节器热警报状态。设置后,由于电压调节器发出热警报,频率降低到低于操作系统要求。8
:电气设计点状态。设置后,由于电气设计点限制(例如最大电流消耗),频率会降低到操作系统要求以下。9
:核心功率限制状态。设置后,由于域级功率限制,频率会降低到低于操作系统请求。10
:封装级功率限制PL1状态。设置后,由于包级功率限制PL1,频率降低到低于操作系统请求。11
:包级功率限制PL2状态。设置后,由于包级功率限制PL2,频率降低到低于操作系统请求。12
:最大Turbo限制状态。设置后,由于多核turbo限制,频率会降低到低于操作系统请求。13
:Turbo转换衰减状态。当设置时,由于Turbo转换衰减,频率降低到操作系统要求以下。这可以防止由于频繁的操作比率更改而导致的性能下降。16
:PROCHOT log17
:热日志20
:图形驱动程序日志21
:基于自主利用率的频率控制日志22
:电压调节器热警报日志24
:电气设计点日志25
:核心功率限制日志26
:包级功率限制PL1 log27
:包级功率限制PL2 log28
:最大Turbo限制日志29
:Turbo转换衰减日志pfc.ko
现在支持这个MSR,演示会显示这些日志位中哪些是活动的。pfc.ko
驱动程序在每次读取时清除粘滞位。
我在打印位的同时重新运行了您的实验,我的CPU报告在非常重的负载下(所有4个内核/8个线程活动)有几个限制因素,包括电气设计点和内核功率限制。由于我不知道的原因,包级PL2和最大Turbo限制位总是在我的CPU上设置。我也看到有时涡轮过渡衰减。
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_alibrary()
毫微秒数(将上面的数字乘以2.4以获得add_alibrary()
)的实际参数)。
这将生成如下所示的日志(250000 nanos的情况):
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
饱和绿点:-3个标准差(低于平均值)
在大约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
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
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
问题内容: 我想在特定时间获取CPU周期。我当时使用此功能: (编者注:是错的x86-64,捡起 _任何_RDX或RAX仅在32位模式下将它挑EDX:你想EAX输出中看到的。 问题是它总是返回一个 递增的 数字(每次运行)。好像是在指绝对时间。 我使用的功能不正确吗? 问题答案: 只要您的线程停留在相同的CPU内核上,RDTSC指令就会一直返回递增的数字,直到它回绕为止。对于2GHz CPU,这种
问题内容: 我正在运行基本的ELK堆栈。在vm中运行的所有三个组件。Logstash正在侦听TCP 9140,以获取其输入通过NxLog代理从大约30个Windows Server 2008s和30个Windows Server 2003事件(evts)中接收的信息,并将其输出到elasticsearch。 这个已经运行了好几个星期了。我可以看到ElasticSearch每天都在创建索引,并且可以
我的spring boot应用程序总是在早上向我显示这个白标签错误:无法打开JPA EntityManager进行事务处理;嵌套异常为javax.persistence.persistenceException:org.hibernate.transactionException:JDBC begin transaction Failed: 对于数据源,我使用spring Data的存储库: 下面
鉴于下面的代码片段,为什么最后四个输出周期是相同的?我希望这些行的天数部分是4,3,2,1,而不是4,4,4,4。这是一个错误还是我遗漏了一些明显的东西?(天晚了,我很累,所以很可能是后者。)我用的是野田佳彦时间1.2.0。
问题内容: 大家好,如果在Java中提供了开始日期和结束日期,那么如何生成日期呢? 像下面这样: 例:如果有并且我希望日期与以下类似,则列表应省略和 我已经完成了以下操作,但是如果日期范围是同一个月,它将生成一个月。` 因此,请为我提供建议。 问候托尼 问题答案: 使用以下乔达时间
问题内容: servlet和过滤器生命周期之间有什么区别吗? 问题答案: 不,一个servlet和一个过滤器: 在上下文开始时实例化(一次) 该方法称为 他们处理每个请求-首先,它通过所有过滤器,然后到达servlet 当上下文被破坏时(即,当您的容器停止运行或从管理器控制台取消部署您的应用程序时),该方法被调用