1. <span id="0jeop"><u id="0jeop"></u></span>

      <s id="0jeop"><dfn id="0jeop"></dfn></s><u id="0jeop"></u>
      <span id="0jeop"></span>

    2. <span id="0jeop"></span>
    3. <u id="0jeop"><meter id="0jeop"></meter></u>

      <u id="0jeop"><meter id="0jeop"></meter></u>
      條碼打印機
      當前位置 : 首 頁 >> 新聞中心 >> 行業資訊

      測量CPU的利器 - TSC

      2022-03-22 09:30:44

      自Pentium開始x86 CPU均引入TSC了,可提供指令級執行時間度量的64位時間戳計數寄存器,隨著CPU時鐘自動增加。

      CPU指令

      rdtsc: Read Time-Stamp Counter
      rdtscp: Read Time-Stamp Counter and Processor ID

      調用:

      Microsoft Visual C++:

      unsigned __int64 __rdtsc();
      unsigned __int64 __rdtscp( unsigned int * AUX );

      Linux & gcc :

      extern __inline unsigned long long
      __attribute__((__gnu_inline__, __always_inline__, __artificial__))
      __rdtsc (void) {
        return __builtin_ia32_rdtsc ();
      }
      extern __inline unsigned long long
      __attribute__((__gnu_inline__, __always_inline__, __artificial__))
      __rdtscp (unsigned int *__A)
      {
        return __builtin_ia32_rdtscp (__A);
      }

      示例:

      1: L1 cache及內存的延遲測量:

      代碼:

      {
          ......
          /* flush cache line */
          _mm_clflush(&data[0]);
      
          /* measure cache miss latency */
          ts = rdtscp(&ui);
          m |= data[0];
          te = rdtscp(&ui);
          CALC_MIN(csci[0], ts, te);
      
          /* measure cache hit latency */
          ts = rdtscp(&ui);
          m &= data[0];
          te = rdtscp(&ui);
            /* flush cache line */
          _mm_clflush(&data[0]);
      
          /* measure cache miss latency */
          ts = rdtscp(&ui);
          m |= data[0];
          te = rdtscp(&ui);
          CALC_MIN(csci[0], ts, te);
      
          /* measure cache hit latency */
          ts = rdtscp(&ui);
          m &= data[0];
          te = rdtscp(&ui);
          CALC_MIN(csci[1], ts, te);
          CALC_MIN(csci[1], ts, te);
      }

      結果:

      rdtscp指令自身耗時:

      問題:讀取1個字節與8個字節的所用的時間是一樣的,為什么?

      2: 常見整型運算及多條指令執行周期:

      代碼:

      {
          ......
          /* measure mul latency */
          ts = rdtscp(&ui);
          m *= *((U32 *)&data[0]);
          te = rdtscp(&ui);
          CALC_MIN(csci[2], ts, te);
      
          /* measure div latnecy */
          ts = rdtscp(&ui);
          m /= *((U32 *)&data[0]);
          te = rdtscp(&ui);
          CALC_MIN(csci[3], ts, te);
      
          /* measure 2*mul latnecy */
          ts = rdtscp(&ui);
          m *= *((U32 *)&data[0]);
          m *= *((U32 *)&data[0]);
          te = rdtscp(&ui);
          CALC_MIN(csci2[0], ts, te);
      
          /* double div */
          ts = rdtscp(&ui);
          m /= *((U32 *)&data[0]);
          m /= *((U32 *)&data[0]);
          te = rdtscp(&ui);
          CALC_MIN(csci2[1], ts, te);
      
          /* mul + div */
          ts = rdtscp(&ui);
          m *= *((U32 *)&data[0]);
          m /= *((U32 *)&data[0]);
          te = rdtscp(&ui);
          CALC_MIN(csci2[2], ts, te);
      
          /* measure float mul latency */
          ts = rdtscp(&ui);
          f = f * m;
          te = rdtscp(&ui);
          CALC_MIN(csci[4], ts, te);
      
          /* measure float div latency */
          while (!m)
              m = rand();
          ts = rdtscp(&ui);
          f = f / m;
          te = rdtscp(&ui);
          CALC_MIN(csci[5], ts, te);
      }

      結果:

      問題:m及n的除法運算的耗時只比m的除法多了一點,但卻明顯少于m的兩次除法,為什么?

      注意事項:

      1.考慮到CPU亂序執行的問題,rdtsc需要配合cpuid或lfence指令,以保證計這一刻流水線已排空,即rdtsc要測量的指令已執行完。后來的CPU提供了rdtscp指令,相當于cpuid + rdtsc,但cpuid指令本身的執行周期有波動,而rdtscp指令的執行更穩定。不過rdtscp不是所有的CPU都支持,使用前要通過cpuid指令查詢是不是支持: 即CPUID.80000001H:EDX.RDTSCP[bit 27]是不是為1

      2.多核系統:新的CPU支持了Invariant TSC特性,可以保證在默認情況下各核心看到的TSC是一致的,否則測量代碼執行時不能調度至其它核心上。另外TSC是可以通過MSR來修改的,這種情況下也要注意:
      Invariant TSC: Software can modify the value of the time-stamp counter (TSC) of a logical processor by using the WRMSR instruction to write to the IA32_TIME_STAMP_COUNTER MSR

      3.CPU降頻問題:第一代TSC的實現是Varient TSC,沒有考慮到降頻的問題,故在低功耗TSC計數會變慢,甚至停止;后來又有了Constant TSC,解決了降頻的問題,但在DEEP-C狀態下依然會發生停止計數的情況,所以又有了具新的Invariant TSC的特性:
      The time stamp counter in newer processors may support an enhancement, referred to as invariant TSC. Processor’s support for invariant TSC is indicated by CPUID.80000007H:EDX[8]. The invariant TSC will run at a constant rate in all ACPI P-, C-. and T-states. This is the architectural behavior moving forward. On processors with invariant TSC support, the OS may use the TSC for wall clock timer services (instead of ACPI or HPET timers). TSC reads are much more efficient and do not incur the overhead associated with a ring transition or access to a platform resource.

      4.指令本身的時間開銷
      Pentinum Gold G5500T: 31 cycles Core i7-7820HQ: 25 cycles

      5.權限問題(此指令可用于時序攻擊,如Meltdown及Spectre):
      CR4.TSD: Time Stamp Disable (bit 2 of CR4) — Restricts the execution of the RDTSC instruction to procedures running at privilege level 0 when set; allows RDTSC instruction to be executed at any privilege level when clear. This bit also applies to the RDTSCP instruction if supported (if CPUID.80000001H:EDX[27] = 1).

      6.計數器溢出可能:計算器本身是64位的,即使是主頻4G的CPU,也要100多年才會溢出,對于我們的測量來說可以不用考慮

      7.時序測量容易被干擾(線程調度、搶占、系統中斷、虛擬化等),要求測量的指令序列盡量短,并且需要進行多次測量


      標簽

      Copyright ? 廣州飛利條碼科技有限公司 All rights reserved 備案號:粵ICP備20033020號 營業執照 主要從事于條碼掃描槍,條碼打印機,數據采集器 , 歡迎來電咨詢! 服務支持:半島網絡
      久久久久成亚洲综合精品久久久久久无码国产精品中文字幕国产黄a一级二级三级看三区av免费观看91精品国产综合久久久久久国产欧美日韩精品一区二区三区蜜桃不卡,亚洲欧美日韩久久精品亚洲欧美日韩国产成人精品影院亚洲国产欧美日韩精品一区二区三区欧美日韩国产成人高清视频欧美日韩在线精品一区二区三区激情综合,亚洲欧美日韩久久精品亚洲欧美日韩国产成人精品影院亚洲国产欧美日韩精品一区二区三区欧美日韩国产成人高清视频欧美日韩在线精品一区二区三区激情综合,精品综合久久久久久五月播播激情综合激情五月俺也去米奇奇米第四色一级特黄aaa大片在线观看视频久久久久久久久毛片精品久久精品视频免费观看v亚洲v日韩v欧美v综合,成人午夜性a一级毛片免费一级黄色毛片亚洲国产一成久久精品国产成人综合91蜜桃国产成人精品区在线亚洲国产精品成人久久综合网久久久久久免费国产精品中文字幕久久精品国产亚洲成人满28免费网站最近日本韩国高清免费观看狠狠综合久久久久综合国产精品欧美一区二区三区免费不卡