2013-06-26 28 views
1

我正在研究一個有很多SIMD內在代碼的代碼庫。現在我們擁有AVX2,我們仍然需要在非AVX2處理器上運行SIMD代碼,這將是更多的工作。此外,AVX2混洗的128bit車道穿越限制也使事情變得複雜。出於這些原因,現在是更多地依靠自動矢量化的好時機。令我感到恐慌的主要原因是單個無辜更改的前景,它會導致並行性和調試自動矢量化代碼的前景,以防出現問題。你可以調試自動矢量化循環嗎?

我編譯使用g ++ -O1 -g -ftree,矢量化以下,並試圖用GDB單步(有沒有人知道爲什麼-ftree,矢量化不-O0工作?)

float a[1000], b[1000], c[1000]; 
int main(int argc, char **argv) 
{ 
    for (int i = 0; i < argc; ++i) 
    c[i] = a[i] + b[i]; 
    return 0; 
} 

但沒有得到任何有意義的結果。例如,有時候,我說的值<優化了>,而其他時間跳躍了20.

看起來主要的問題是,難以將SIMD狀態映射到原始C狀態進行調試。但實際上,它可以做到嗎?

+0

你爲什麼要調試它?如果你想驗證它是矢量化的,檢查彙編代碼還是運行基準測試(在完全優化設置下)不是更好嗎?如果您想查找錯誤,請調試非矢量化版本(以及未優化的版本)。 – delnan

+0

是的,編譯器的bug在發生時會很討厭。我不知道(源代碼級別)調試器是否是正確的工具,但無論如何,我都明白。 – delnan

+0

因此,遠程調試錯誤大多是假設性的。我絕對記得在Visual C++ 2010 vectorizer中提交了一個bug,導致它將一個未對齊的加載與算術指令錯誤地融合爲一個x86指令,導致它在非對齊數組上運行時崩潰。 –

回答

0

在自動矢量化代碼上使用調試器非常棘手,尤其是,當你想檢查需要不同行爲的變量時(例如循環計數器)。

您可以使用調試版本(-O0-Og),也可以瞭解編譯器如何向量化代碼,並檢查寄存器asm和寄存器。根據您需要跟蹤哪種錯誤,您可能會或可能不會遇到自動矢量化構建的問題。

它聽起來像評論你似乎更感興趣的是檢查自動矢量化的效率,而不是實際調試來修復代碼中的邏輯錯誤。看看這些asm和基準,可能是你最好的選擇。 (即使是在調用之前/之後的簡單rdtsc,或者在測試性能以及正確性的單元測試中)。

有時,編譯器將生成循環的多個版本,例如,對於輸入數組重疊的情況以及不存在的情況。單步執行(通過指令,使用stepi,在gdb中使用layout asm)可以提供幫助,直到找到實際完成大部分工作的循環爲止。然後你可以專注於它是如何矢量化的。如果你想消除檢查和替代版本,restrict指針可能會有所幫助。還有p = __builtin_assume_aligned(p, 16)

您也可以使用Intel's free code analyzer來嘗試靜態分析迭代需要多少個週期。將IACA標記放在循環體的頂部,並在循環的閉合後,希望GCC將它們放在自動矢量化循環中的適當位置,並且內聯asm不會破壞自動矢量化。

沒有優化答案將完成鏈接到http://agner.org/optimize/,所以你在這裏。