[英]gcc auto-vectorization fails in a reduction loop
我試圖用自動矢量化標志編譯我的代碼,但我在一個非常簡單的減少循環中遇到了失敗:
double node3::GetSum(void){
double sum=0.;
for(int i=0;i<8;i++) sum+=c_value[i];
return sum;
}
其中c_value[i]
數組定義為
class node3{
private:
double c_value[9];
自動向量化編譯返回:在node3.cpp處分析循環:10
node3.cpp:10: note: step unknown.
node3.cpp:10: note: reduction: unsafe fp math optimization: sum_6 = _5 + sum_11;
node3.cpp:10: note: Unknown def-use cycle pattern.
node3.cpp:10: note: Unsupported pattern.
node3.cpp:10: note: not vectorized: unsupported use in stmt.
node3.cpp:10: note: unexpected pattern.
node3.cpp:8: note: vectorized 0 loops in function.
node3.cpp:10: note: Failed to SLP the basic block.
node3.cpp:10: note: not vectorized: failed to find SLP opportunities in basic block.
我真的不明白為什么它無法確定SLP的基本塊例如。 此外,我想我不明白什么是“stmt中不支持的使用”:這里的循環簡單地總結了一個順序訪問數組。
c_value[]
是否在類的private
中定義,是否會導致此類問題?
提前致謝。
注意:編譯為g++ -c -O3 -ftree-vectorizer-verbose=2 -march=native node3.cpp
,並嘗試使用更具體的-march=corei7
但結果相同。 GCC版本:4.8.1
我設法使用以下技巧在結尾處對循環進行矢量化:
double node3::GetSum(void){
double sum=0.,tmp[8];
tmp[0]=c_value[0]; tmp[1]=c_value[1]; tmp[2]=c_value[2]; tmp[3]=c_value[3];
tmp[4]=c_value[4]; tmp[5]=c_value[5]; tmp[6]=c_value[6];tmp[7]=c_value[7];
for(int i=0;i<8;i++) sum+=tmp[i];
return sum;
}
我在哪里創建了虛擬數組tmp[]
。 這個技巧,再加上另一個編譯標志,即-funsafe-math-optimizations
(@Mysticial:這實際上是我唯一需要的東西, -ffast-math
與其他我顯然不需要的東西),使自動矢量化成功。
現在,我真的不知道這個解決方案是否真的加快了執行速度。 它確實是矢量化,但我添加了一個賦值操作,所以我不確定它是否應該運行得更快。 我的感覺是,從長遠來看(多次調用該功能)它會加速一點,但我無法證明這一點。 無論如何,這是矢量化問題的可能解決方案,所以我發布了答案。
令人討厭的是,矢量化減少的自由與其他(字面上)不安全的優化相結合。 在我的示例中,使用-mavx和-funsafe-math-optimizations組合出現了一個錯誤(使用gcc而不是g ++),其中一個永遠不會被觸及的指針會被破壞。 自動向量化並不能始終如一地加速這種短循環,特別是因為在更常見的CPU上使用hadd指令的總和減少結尾很慢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.