2013-05-27 42 views
1

我一直試圖採取一些Lua代碼的microbenchmarks,但遇到了令人難以置信的惱人的問題:我似乎無法得到一致的結果。嘗試microbenchmark結果不一致

例子:這裏是一個的應該是時間天真的斐波那契功能的死簡單的Lua程序:

function pfibs(n) 
    if n ~= math.floor(n) then return 0 
    elseif n < 0 then return pfibs(n + 2) - pfibs(n + 1) 
    elseif n < 2 then return n 
    else return pfibs(n - 1) + pfibs(n - 2) 
    end 
end 
t = os.clock() 
pfibs(30) 
t = os.clock() - t 
print("time: "..t) 

當我嘗試在連續跑了好幾次,這樣的事情發生了:

$ lua fib.lua 
time: 1.265 
$ lua fib.lua 
time: 1.281 
$ lua fib.lua 
time: 1.343 
$ lua fib.lua 
time: 1.437 
$ lua fib.lua 
time: 1.562 
$ lua fib.lua 
time: 1.578 
$ lua fib.lua 
time: 1.64 
$ lua fib.lua 
time: 1.703 
$ lua fib.lua 
time: 1.75 
$ lua fib.lua 
time: 1.797 
$ lua fib.lua 
time: 1.796 
$ lua fib.lua 
time: 1.812 
$ lua fib.lua 
time: 1.89 

(這僅僅是一個例子,爲簡潔起見,但代表性的是我看到的那種減速曲線)

從1.1秒開始的時間最終很好兩秒以上。我所做的一切都是坐在這裏反覆敲擊。如果我在呼叫time而不是使用Lua時鐘的情況下將測試包裝進來,或者如果再循環幾次再花費幾秒鐘時間,就會發生同樣的事情;它似乎成比例地放緩。如果我離開它一段時間,有時候時間會縮短。有時候不是(可能是因爲我不知道要離開多久)。

這是在Windows + MSYS上。在Ubuntu(同一臺機器)上嘗試這種方式會導致不同的模式,但仍然會出現極其不一致和不可用的結果(例如,測試需要2秒,然後3.5秒,然後4秒,然後2.5秒...)。在任何情況下,任務管理器/頂部都不會在後臺咀嚼CPU。 CPU速度切換被禁用。

我在做什麼錯?我的機器是舊的,但它不能損壞(當然,如果它是機器的錯誤,每一個程序每秒都會慢得多,我會注意到它是不可用的)。


什麼我其實想做:

做的是瞭解解釋實施後,有香草的Lua開始,調整它,看看對翻譯有什麼影響的變化性能。正如你所看到的,我還沒有過去「建立一個控制」,所以我還沒有實際做過這樣的事情 - 基準方差與上述一樣高,所做的任何改變都將完全喪失在噪聲。我選擇了Lua,因爲雖然它是一個真實世界的程序,但它也很小且易於閱讀和修改。如果有一個更好的基礎翻譯人員來解決這個問題,或者建立了最佳的解釋器性能基準測試方法,請隨時爲這些問題添加建議。


編輯:添加C標籤,因爲同樣的事情在C程序中使用傳統的C時序水電費以及發生的,如:

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

int fib(int n) { 
    return n > 2 ? fib(n - 1) + fib(n - 2) : n; 
} 

int main(void) { 
    clock_t t1, t2; const int ITNS = 30; 
    for (int i = 0; i < ITNS; i ++) { 
     t1 = clock(); 
     fib(38); 
     t2 = clock(); 
     printf("time: %d\n", (int)((t2 - t1)/(CLOCKS_PER_SEC/1000))); 
    } 
    return 0; 
} 

...打印如下:

time: 687 
time: 688 
time: 687 
time: 688 
time: 671 
time: 688 
time: 687 
time: 688 
time: 672 
time: 687 
time: 688 
time: 687 
time: 672 
time: 688 
time: 687 
time: 688 
time: 672 
time: 796 
time: 766 
time: 719 
time: 969 
time: 1000 
time: 1015 
time: 1000 
time: 1016 
time: 1000 
time: 1000 
time: 1015 
time: 1000 
time: 1000 

這表示效果不限於單獨運行。我想這意味着機器或操作系統有問題。

+0

我認爲這與操作系統無關,因爲整個計算都是在用戶空間中進行的。 – Naruil

+0

我已經在我的英特爾和AMD服務器上測試了您的c程序,並且始終保持穩定。你能在這裏發佈你的機器/操作系統規格嗎? – Naruil

+0

您應該做的一件事是將州長設置從按需或節能改爲性能。另請參閱Crypto ++項目中的''governor.sh'](https://github.com/weidai11/cryptopp/blob/master/TestScripts/governor.sh),該項目從OpenSSL項目的Andy Polyakov借用。 – jww

回答

3

你的程序似乎是很穩定我的機器上使用的Xeon E7-4850

time: 0.97 
time: 0.98 
time: 1 
time: 0.98 
time: 1.01 
time: 1 
time: 0.98 
time: 0.98 
time: 1.02 
time: 0.98 

不過,我建議你啓用檢查CPU頻率縮放或類似渦輪增壓當你運行基準測試。我們以前遇到過類似的問題,但是當我們關閉CPU頻率調整功能時,基準變得穩定。在Linux上,您可以使用cpufrequtils將其關閉。另外,如果您使用的是AMD機器,我建議您只需切換到英特爾版本,因爲即使CPU頻率固定,lua程序的性能對於我們的Opteron 8431仍然不穩定。因此,此問題可能取決於硬件平臺而不是Lua解釋器本身。

編輯:

我覺得這是更好地閱讀和打印當前CPU頻率(從/ proc/cpuinfo中或/ dev/CPU /#/ MSR)每次迭代之後,以確保頻率穩定。

您的C程序結果有兩個清晰的穩定階段。看起來在run19和cpu頻率下降後發生了一些事情。

enter image description here

+0

我在發佈問題前禁用了頻率縮放;雖然我只是在我注意到問題後纔想到,但在時間上似乎沒有任何影響。 – Leushenko

0

rdtsc基於時間測量是通過CPU頻率變化的影響。
您可以嘗試在LuaJIT基準測試與重新定義os.clock功能按以下方式
(只設置要顯示的似乎合理的時間值CPU_speed常數):

-- New os.clock() implementation based on rdtsc instruction, LuaJIT required 
do 
    local CPU_speed = 3.0 -- Your CPU speed in GHz 
    local rdtsc = require'ffi'.cast(
     '__cdecl uint64_t(*)()', 
     '\x0F\x31\xC3' -- rdtsc, ret 
    )     -- This trick may not work on modern 64-bit OS 
    local rdtsc0 = rdtsc() 
    os.clock = function() 
     return tonumber(rdtsc() - rdtsc0)/(CPU_speed * 10^9) 
    end 
end 
+1

用C而不是LuaJIT試過,但不幸的是'rdtsc'似乎表現出相同的模式。問題出在哪裏,就在別的地方。 – Leushenko

+0

問題似乎在您的操作系統端。在測試時檢查CPU使用情況(如果您擁有2個或更多CPU核心)和內存使用情況。可能之前的流程在新流程啓動之前未被終止? –

+0

我已經用一個例子更新了這個問題,這個例子顯示了在同一個程序中也發生了這種情況......並且我猜這意味着它畢竟不是一個編程問題;電腦可能是過熱或什麼的。 – Leushenko

0

不知道到什麼程度,這是技術上「解決方案」,但是:

我能夠通過關閉頻率縮放(如所建議的)來顯示問題,但鎖定CPU速度爲「始終爲低」而不是「始終爲高」。時間現在一直在彼此的1%以內,就像其他人的機器一樣。

使用CPU-Z,我注意到溫度在突然減速的同時也出現了峯值。它只從60度跳到72度(在a CPU that supposedly goes up to 100 degrees),但存在相關性。隨着頻率鎖定在低位,這不再發生,放緩也不會發生。

我在想這個問題可以歸結爲「我的電腦老舊不可靠」,並且應該關閉這個問題,因爲它顯然不是一個真正的一般編程問題。

儘管感謝您的幫助。

+0

不,這種行爲是預期的。無論您是否禁用了頻率縮放,CPU都會自動在高溫下進行節流。有時甚至可以在BIOS配置中調整閾值。 100度是CPU的最高允許溫度,在這種情況下它將直接關閉。我建議你清理機器內部的灰塵,然後再試一次^ _ ^ – Naruil