代码之家  ›  专栏  ›  技术社区  ›  BeeOnRope

Intel上的丢失周期?rdtsc和CPU\u CLK\u UNHALTED.REF\u TSC之间不一致

  •  34
  • BeeOnRope  · 技术社区  · 7 年前

    在最近的CPU上(至少在过去十年左右),除了各种可配置的性能计数器外,Intel还提供了三个固定功能硬件性能计数器。三个固定计数器为:

    INST_RETIRED.ANY
    CPU_CLK_UNHALTED.THREAD
    CPU_CLK_UNHALTED.REF_TSC
    

    此事件统计TSC速率下的参考循环数 磁芯不处于停止状态,也不处于TM停止时钟状态。这个 核心在运行HLT指令或 MWAIT指令。该事件不受核心频率的影响 邮票计数器。此事件可以近似计算内核运行时经过的时间

    rdstc ,因为它们只应在暂停周期指令或“TM stopclock状态”是什么的情况下发散。

    我用以下循环(整个 standalone demo is available on github

    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);
    }
    

    定时区域中唯一重要的事情是 busy_loop(CALIBRATION_LOOPS); 这只是一个由易变存储组成的紧密循环 as compiled gcc clang 在最近的硬件上,每次迭代执行一个周期:

    void busy_loop(uint64_t iters) {
        volatile int sink;
        do {
            sink = 0;
        } while (--iters > 0);
        (void)sink;
    }
    

    这个 PFCSTART PFCEND CPU_CLK_UNHALTED.REF_TSC 计数器使用 libpfc __rdtsc() 是一个通过 rdtsc 指示最后,我们使用 nanos() 简单来说就是:

    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 ,事情并不是以一种精确的方式交错的,但校准循环是一整秒钟,所以这种纳秒级的问题只是被稀释到或多或少没有。

    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公司 指示 Eff Mhz Ratio 是的比率 参考TSC rdtsc公司

    从图形上看,它看起来像这样 :

    PMU tsc vs rdstc

    这个 准确的 后果 1.

    如果我 然而,结果更加一致:

    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
    

    小数点后6位

    从图形上看(Y轴比例强制与前一个图形相同):

    PMU vs rdtsc (no turbo)

    现在代码只是运行一个热循环,应该没有 hlt mwait 当然,没有什么会暗示变化超过10%。我不能说 “TM停止时钟周期”是什么,但我敢打赌它们是“热管理停止时钟周期”,这是一种在CPU达到其最高温度时临时调节CPU的技巧。然而,我查看了集成热敏电阻读数,我从来没有看到CPU打破60摄氏度,远低于90摄氏度-100摄氏度,在90摄氏度-100摄氏度,终端管理踢(我认为)。


    1. 事实上,有一段时间我真的 准确的 2591.97 MHz -一次又一次的迭代。然后有些事情发生了变化,我不确定是什么,在这个过程中有大约0.1%的微小变化 后果一种可能性是逐渐调整时钟,由Linux计时子系统进行,以使本地水晶衍生时间与 ntpd 确定的时间。也许,这只是一个晶体漂移-上面的最后一个图形显示了测量周期的稳定增加 每秒钟。

    2. 图形与文本中显示的值不对应,因为我不会每次更改文本输出格式时都更新图形。然而,每次跑步的定性行为基本相同。

    1 回复  |  直到 7 年前
        1
  •  30
  •   Iwillnotexist Idonotexist    7 年前

    TL;博士

    RDTSC REFTSC REF_TSC ,停止约20000-21000个循环(8.5us),但 rdtsc 它可能处于一个孤立的电源和时钟域中,因为它非常重要,而且有记录在案的类似挂钟的行为。

    这个 RDTSC-REFTSC

    这种差异表现为 RDTSC公司 REFTSC公司 .程序运行的时间越长,差异越大 倾向于。在很长一段时间内,它可以上升到1%-2%,甚至更高。

    intel_pstate :

    echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
    

    可能节流?

    TurboBoost是一种动态频率和电压缩放解决方案,可机会性地利用工作包线(热或电)中的净空。在可能的情况下,TurboBoost会将处理器的核心频率和电压放大到标称值以上,从而以更高的功耗为代价来提高性能。

    当然,更高的功耗会增加核心温度和功耗。最终,将达到某种极限,涡轮增压器将不得不降低性能。

    TM1热节流?

    我首先调查了热监测器1(TM1)或2(TM2)的热控制电路(TCC)是否导致热节流。TM1通过插入TM停止时钟周期来降低功耗,这些是导致停止的条件之一 REFTSC公司

    libpfc() IA32_PACKAGE_THERM_STATUS IA32_THERM_STATUS MSRs。两者都包含一个只读状态和一个针对各种热条件的读写硬件粘性日志标志:

    IA32_THERM_STATUS register contents IA32\u PACKAGE\u THERM\u状态 寄存器基本相同)

    虽然其中一些是偶尔设置的(尤其是在堵塞笔记本电脑通风口时!),他们似乎与 RDTSC公司 无论热状态如何,都会可靠地发生过计数。

    在SDM的其他地方挖掘在HDC(硬件占空比)上发生的类似停止时钟的硬件,通过这种机制,操作系统可以手动请求CPU只运行固定比例的时间;HDC硬件通过每16个时钟周期运行处理器1-15个时钟周期来实现这一点,以及 它适用于该周期剩余的15-1个时钟周期。

    HDC提供了非常有用的寄存器,尤其是MSR:

    • IA32_THREAD_STALL
    • MSR_CORE_HDC_RESIDENCY :同上,但对于物理处理器,当此核心的一个或多个逻辑处理器强制空闲时,统计周期。
    • MSR_PKG_HDC_SHALLOW_RESIDENCY
    • MSR_PKG_HDC_DEEP_RESIDENCY :统计包处于更深(可精确配置)C状态且至少一个逻辑处理器强制空闲的周期。

    有关更多详细信息,请参阅英特尔SDM第3卷第14章, §14.5.1硬件负载循环编程接口

    其他节流源?

    在Intel SDM中挖掘更多信息,我发现了一个 非常非常 MSR_CORE_PERF_LIMIT_REASONS 。该寄存器报告了大量非常有用的状态和粘性日志位:

    690H MSR\u CORE\u PERF\u LIMIT\u REASONS-Package-处理器内核中频率限幅的指示器

    • 0 : PROCHOT状态
    • 1 :
    • 一点 4 :
    • 一点 5 : 基于自主利用的频率控制状态
    • 一点 6 : 电压调节器热警报状态 .设置后,由于电压调节器发出热警报,频率降低到操作系统请求以下。
    • 8 : 电气设计点状态
    • 一点 9 堆芯功率限制状态 。设置后,由于域级功率限制,频率降低到操作系统请求以下。
    • 一点 10 :
    • 一点 11 : 封装级功率限制PL2状态
    • 一点 12 : .设置后,由于多核turbo限制,频率降低到操作系统要求以下。
    • 一点 13 .设置后,由于Turbo过渡衰减,频率降低到操作系统要求以下。这可以防止由于频繁的工作比变化而导致性能下降。
    • 一点 16 :
    • 一点 17 :
    • 20 : 图形驱动程序日志
    • 一点 21 基于自主利用的频率控制日志
    • 22 电压调节器热警报日志
    • 一点 24 :
    • 一点 25 : 堆芯功率限制日志
    • 26 : 封装级功率限制PL1日志
    • 27 :
    • 一点 28 :
    • 一点 29 涡轮过渡衰减测井

    pfc.ko 现在支持此MSR,并且 demo 驱动程序在每次读取时清除粘性位。

    我在打印位的同时重新运行你的实验,我的CPU报告在非常重的负载下(所有4核/8线程都处于活动状态)几个限制因素,包括 电气设计点 这个 位是 始终设置 .

    RDTSC-REFTSC 存在 属于 这意味着切换P态有足够的成本,因此必须通过一些滞后机制进行速率限制。当我找不到统计这些转换的MSR时,我决定做下一件最好的事情——我将使用 RDTSC-REFTSC

    实验

    实验装置如下。在我的i7-4700MQ CPU上,标称速度为2.4GHz,最大涡轮速度为3.4 GHz,我将使除0(启动处理器)和3(一个方便的受害者核心,编号不为0,并且不是0的逻辑同级)之外的所有内核脱机。然后我们将询问 英特尔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
    

    我运行了 demo 申请

    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
    

    纳秒/秒 add_calibration() 添加校准() ).

    后果

    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
    

    我对这些日志进行了几次观察,但有一次比较突出:

    对于Nano<~250000,RDTSC过度计算可以忽略不计。对于Nano>~250000,可以可靠地观察到过计数时钟周期 量子 超过20000个时钟周期。但他们是 由于用户操作系统转换。

    Image showing quantized TurboBoost transition penalties 饱和蓝点:0标准差(接近平均值)

    饱和绿点:-3个标准差(低于平均值)

    纳米级<250000

    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
    

    表明涡轮增压比在33倍时非常稳定 RDTSC公司 这与 以24倍的速率 REF_XCLK (100 MHz),可以忽略不计的过计数,通常在内核中花费0个周期,因此0个过渡到内核。内核中断大约需要3000个参考周期才能提供服务。

    纳米==250000

    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
    

    结论

    涡轮增压器机械对 .该差异可用于确定从3.3 GHz到3.4 GHz的涡轮增压状态转换需要约20500个参考时钟周期(8.5us),并且在进入后不迟于约250000 ns(250us;600000个参考时钟周期)触发 add_reference() ,当处理器确定工作负载足够密集,需要进行频率电压调整时。

    今后的工作

    需要做更多的研究来确定转换成本如何随频率变化,以及选择功率状态的硬件是否可以调整。我特别感兴趣的是“Turbo衰减单元”,我在网络的各个角落都看到过这方面的提示。也许Turbo硬件有一个可配置的时间窗口?目前,决定转换所花费的时间与转换所花费的时间之比为30:1(600us:20us)。可以调整吗?