<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 引言 可能你認為的 90% CPU 利用率意味著這樣的情形: ![](https://ws2.sinaimg.cn/large/006tNc79ly1g1sp3jhxpfj30u002i0sl.jpg) 而實際卻可能是這樣的 ![](https://ws4.sinaimg.cn/large/006tNc79ly1g1sp57jf53j30u002lt8m.jpg) CPU 并非 90% 的時間都在忙著,很大一部分時間在等待,或者說“**停頓(Stalled)**”了。這種情況表示處理器流水線停頓,一般由**資源競爭、數據依賴**等原因造成。多數情況下表現為等待訪存操作,其中又以**讀操作為主**。在停頓周期內,**不能執行指令**,這意味著你的程序不往前走。值得注意的是,圖中 “Stalled” 狀態所占的比例是作者依據生產環境中的典型場景計算而來,具有普遍現實意義。因此,大多時候 CPU 處于停頓狀態,而你卻不知道,因為 CPU 利用率這個指標沒有告訴你真相。通過進一步分析 CPU 停頓的原因,可以指導代碼優化,提高執行效率,這是我們深入理解CPU微架構的動力之一。 # CPU 利用率的真實含義是什么? 我們通常所說的CPU利用率是指 “**non-idle time**”:即CPU不執行 idle thread 的時間。操作系統內核會在上下文切換時記錄CPU的運行時間。假設一個 non-idle thread 開始運行,100ms 后結束,內核會認為這段時間內 CPU 利用率為 100%。這種度量方式源于分時復用系統。早在阿波羅登月艙的導航計算機中,idle thread 當時被叫做 “DUMMY JOB”,工程師通過比對運行 “DUMMY JOB” 和 “實際任務” 的時間來衡量導航系統的利用率。 那么這個所謂“利用率”的問題在哪兒呢? 當今時代,CPU 執行速度遠遠大于內存訪問速度,等待訪存的時間成為占用 CPU 時間的主要部分。當你在 top 中看到很高的 “%CPU”,你可能認為處理器是瓶頸,但實際上卻是內存。在過去很長一段時間內,CPU 頻率增長的速度大于 DRAM 訪存延時降低的速度(CPU DRAM gap),直到2005年前后,處理器廠商們才開始放棄“頻率路線”,轉向多核、超線程技術,再加上多處理器架構,這些都導致訪存需求急劇上升。盡管廠商通過增大 cache 容量、優化 cache 策略、提升總線帶寬來試圖緩解訪存瓶頸,但我們的程序仍深受 CPU stall 困擾。 # 如何真正辨別 CPU 在做些什么? 在 PMC(Performance Monitoring Counters) 的幫助下,我們能看到更多的 CPU 運行狀態信息。下圖中,`perf`?采集了10秒內全部 CPU 的運行狀態。 ```bash # perf stat -a -- sleep 10 Performance counter stats for 'system wide': 320075.987964 cpu-clock (msec) # 31.997 CPUs utilized 75,544 context-switches # 0.236 K/sec 4,044 cpu-migrations # 0.013 K/sec 668 page-faults # 0.002 K/sec 6,330,615,683 cycles # 0.020 GHz 2,201,747,556 instructions # 0.35 insn per cycle 447,782,180 branches # 1.399 M/sec 26,550,335 branch-misses # 5.93% of all branches 10.003433562 seconds time elapsed ``` 這里我們重點關注的核心度量指標是 **IPC(instructions per cycle)**,它表示`平均每個 CPU cycle 執行的指令數量`,很顯然該數值越大性能越好。上圖中 IPC 為 0.78,看起來還不錯,是不是 78% busy 呢?現代處理器一般有多條流水線,運行?`perf`?的那臺機器,IPC 的理論值可達到 4.0。如果我們從 IPC? 的角度來看,這臺機器只運行到其處理器最高速度的 19.5%(0.78 / 4.0)。幸運的是,在處理器內部,有很多 PMU event,可用來幫助我們分析造成 CPU stall 的原因。用好 PMU 需要我們熟悉處理器微架構,可以參考 Intel SDM。 # 最佳實踐是什么? 如果 IPC < 1.0, 很可能是 Memory stall 占主導,可從軟件和硬件兩個方面考慮這個問題。軟件方面:減少不必要的訪存操作,提升 cache 命中率,盡量訪問本地節點內存;硬件方面:增加 cache 容量,加快訪存速度,提升總線帶寬。 如果IPC > 1.0, 很可能是計算密集型的程序。可以試圖減少執行指令的數量:消除不必要的工作。火焰圖CPU flame graphs,非常適用于分析這類問題。硬件方面:嘗試超頻、使用更多的 core 或 hyperthread。作者根據PMU相關的工作經驗,設定了1.0這個閾值,用于區分訪存密集型(memory-bound)和計算密集型(cpu-bound)程序。讀者可以根據自己的實際工作平臺,合理調整這個閾值。 # 性能工具應該告訴我們什么? 作者認為,性能工具中使用 %CPU 時都應該附帶上 IPC,或者將 %CPU 拆分為指令執行消耗 cycle(%INS) 和 stalled 的 cycle(%STL)。對應到?`top`,在 Linux 系統有一個能夠顯示每個處理器 IPC 的工具?`tiptop`:
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看