2014-11-21 67 views
6

我一直在試圖用一個簡單的分析器來測量學校服務器上一些C代碼的效率,而且我遇到了一個奇怪的情況。經過短時間(半秒鐘)後,處理器突然開始執行兩倍的指令。我已經測試了幾乎所有我能想到的原因(緩存,內核負載平衡,因休眠而改變CPU頻率),但一切似乎都正常。爲什麼我的CPU突然以兩倍的速度工作?

爲什麼它值得我在學校的linux服務器上做這個測試,所以可能有一個我不知道的不尋常的配置,但是使用的處理器ID不會改變,並且(通過top )服務器在我測試時完全空閒。

測試代碼:

#include <time.h> 
#include <stdio.h> 

#define MY_CLOCK CLOCK_MONOTONIC_RAW 
// no difference if set to CLOCK_THREAD_CPUTIME_ID 

typedef struct { 
     unsigned int tsc; 
     unsigned int proc; 
} ans_t; 

static ans_t rdtscp(void){ 
     ans_t ans; 
     __asm__ __volatile__ ("rdtscp" : "=a"(ans.tsc), "=c"(ans.proc) : : "edx"); 
     return ans; 
} 

static void nop(void){ 
     __asm__ __volatile__ (""); 
} 

void test(){ 
     for(int i=0; i<100000000; i++) nop(); 
} 

int main(){ 
     int c=10; 
     while(c-->0){ 
       struct timespec tstart,tend; 
       ans_t start = rdtscp(); 
       clock_gettime(MY_CLOCK,&tstart); 
       test(); 
       ans_t end = rdtscp(); 
       clock_gettime(MY_CLOCK,&tend); 
       unsigned int tdiff = (tend.tv_sec-tstart.tv_sec)*1000000000+tend.tv_nsec-tstart.tv_nsec; 
       unsigned int cdiff = end.tsc-start.tsc; 
       printf("%u cycles and %u ns (%lf GHz) start proc %u end proc %u\n",cdiff,tdiff,(double)cdiff/tdiff,start.proc,end.proc); 
     } 
} 

輸出我看到:

351038093 cycles and 125680883 ns (2.793091 GHz) start proc 14 end proc 14 
350911246 cycles and 125639359 ns (2.793004 GHz) start proc 14 end proc 14 
350959546 cycles and 125656776 ns (2.793001 GHz) start proc 14 end proc 14 
351533280 cycles and 125862608 ns (2.792992 GHz) start proc 14 end proc 14 
350903833 cycles and 125636787 ns (2.793002 GHz) start proc 14 end proc 14 
350924336 cycles and 125644157 ns (2.793002 GHz) start proc 14 end proc 14 
349827908 cycles and 125251782 ns (2.792997 GHz) start proc 14 end proc 14 
175289886 cycles and 62760404 ns (2.793001 GHz) start proc 14 end proc 14 
175283424 cycles and 62758093 ns (2.793001 GHz) start proc 14 end proc 14 
175267026 cycles and 62752232 ns (2.793001 GHz) start proc 14 end proc 14 

我得到類似的輸出(它採取了不同數量的測試效率提高一倍)使用不同的優化級別(-O0到-O3)。

它可能與超線程有關,其中物理內核中的兩個邏輯內核(服務器使用至強X5560可能會產生這種影響)可以以某種方式「合併」以形成一個兩倍速的處理器?

+0

這難道不是CPU限制的常見現象嗎? – xbug 2014-11-21 21:47:53

+0

我認爲它起初是CPU節流,但我從週期/時間計算GHz,它在2.793處非常一致(這是/ proc/cpuinfo報告的速度)。如果CPU被限制,那麼這個值是不是會減半? – dooglius 2014-11-21 21:51:20

+2

您應該閱讀關於'Turbo Boost'的信息,我很確定該CPU可用。 – Petesh 2014-11-21 21:57:20

回答

0

某些CPU在芯片上進行了優化,這些代碼正在學習您的代碼通常採用的路徑。通過成功預測下一條if語句會做什麼,不需要放棄隊列,並從頭開始全新加載所有新操作。根據芯片和算法,可能需要5到10個週期,直到它成功預測if語句。但不知何故,也有理由說這是造成這種行爲的原因。看看你的輸出我會說這也許只是OS和/或那裏使用的CPU頻率調節器的調度。你確定在你的代碼執行過程中CPU頻率不會改變嗎?沒有CPU提升? 使用像cpufreq這樣的linux工具通常用來調節CPU頻率。

+0

我的投票同樣是[分支預​​測](http://en.wikipedia.org/wiki/Branch_predictor) – Soren 2014-11-21 22:03:59

+7

這裏涉及的時間範圍太大了,因爲這是分支預測的一個工件。花費數百萬個週期來「鎖定」的分支預測器是毫無用處的。 – Mysticial 2014-11-21 22:05:19

+0

你是完全正確的。它早該鎖定了。只有最外層的循環可能需要很長時間才能預測,但這個對執行時間幾乎沒有貢獻。 – user3387542 2014-11-22 10:27:01

-1

超線程意味着複製寄存器空間,而不是實際的解碼/執行單元 - 所以這不是一個解決方案。

爲了測試微基準測試方法,我會做以下的精度:

  1. 運行具有高優先級
  2. 程序計數的指令數,看它是否是正確的。我會這樣做,使用perf stat ./binary - 這意味着你需要有perf。我會多次執行此操作,並查看時鐘和指令度量標準,以瞭解多個指令如何在單個週期內執行。

我有一些補充說明

對於每個NOP也爲比較和條件跳轉在for循環。如果你真的想要執行的NOP我會寫這樣的語句:

#define NOP5 __asm__ __volatile__ ("nop nop nop nop nop"); 
#define NOP25 NOP5 NOP5 NOP5 NOP5 NOP5 
#define NOP100 NOP25 NOP25 NOP25 NOP25 
#define NOP500 NOP100 NOP100 NOP100 NOP100 NOP100 
... 
for(int i=0; i<100000000; i++) 
{ 
    NOP500 NOP500 NOP500 NOP500 
} 

這個構造將允許你做的其實NOP的的比較,而不是與我100M

+0

我並沒有完全明白你認爲會降低執行/解碼帶寬,而是建議改變nop/branch比率的+1。 – Leeor 2014-11-24 16:50:19

+0

Downvoted表示分支預測或利用ILP的超標量處理器會導致此問題。這是100%錯誤。 – 2014-11-25 04:47:23

+0

@CraigAnderson爲什麼這是錯的?由於頻率縮放非常不可能,原因是什麼? – VAndrei 2014-11-25 09:23:00

1

某些系統根據系統負載縮放處理器速度。正如您剛剛注意到的那樣,這在基準測試中尤其令人討厭。

如果您的服務器運行Linux,請鍵入

cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 

如果輸出ondemandpowersaveuserspace,那麼CPU頻率調節是有效的,你會發現它很難做到基準。如果這說performance,那麼CPU頻率縮放將被禁用。

+0

在第一次運行中,它輸出2.7ghz。要獲得最後一次運行的性能,它需要5.4 ghz ...你真的確定它是節流嗎? downvoting時也請評論。 – VAndrei 2014-11-23 23:24:21

+0

@VAndrei由於回覆顯然是不正確的 - 我沒有辦法在這些時間尺度上進行分支預測或超標量執行。對此已有評論,所以我沒有添加重複評論。 – jch 2014-11-23 23:26:02

+0

jch,您對我們的答案有何反駁? user3387542已經表明了頻率縮放的可能性,並指出了州長,但你低估了他的答案。我還添加了額外的信息和驗證方法。我也質疑你的回答,但你沒有提供一個論點。 – VAndrei 2014-11-24 09:00:01

相關問題