2015-05-08 66 views
13

這裏有一些免費的功能,但是在第一種情況下,循環沒有向量化,但在其他情況下是這樣。這是爲什麼?從編譯器(VS2013)爲什麼向量化對於幾乎相同的代碼表現不同?

#include <vector> 

typedef std::vector<double> Vec; 

void update(Vec& a, const Vec& b, double gamma) { 
    const size_t K = a.size(); 
    for (size_t i = 0; i < K; ++i) { // not vectorized 
     a[i] = b[i] * gamma - a[i]; 
    } 
} 

void update2(Vec& a, const Vec& b, double gamma) { 
    for (size_t i = 0; i < a.size(); ++i) { // vectorized 
     a[i] = b[i] * gamma - a[i]; 
    } 
} 

void update3(Vec& a, size_t K, const Vec& b, double gamma) { 
    for (size_t i = 0; i < K; ++i) { // vectorized 
     a[i] = b[i] * gamma - a[i]; 
    } 
} 

int main(int argc, const char* argv[]) { 
    Vec a(argc), b; 
    update(a, b, 0.5); 
    update2(a, b, 0.5); 
    update3(a, a.size(), b, 0.5); 
    return 0; 
} 

相關的消息:

1> c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(7) : info C5002: loop not vectorized due to reason '1200' 
1> c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(13) : info C5001: loop vectorized 
1> c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(19) : info C5001: loop vectorized 

從評論由@tony

原因1200:「循環包含阻止 矢量循環攜帶數據依賴性。循環的不同迭代會干擾其他每個循環,使向量化循環會產生錯誤的答案,並且自動向量化器c annot證明自己沒有這樣的數據 依賴。「 source

+2

試試不同的編譯器?其他人(gcc和clang)將矢量化所有3個功能。 –

+1

什麼是「原因1200」記錄爲? –

+1

原因1200:「循環包含循環執行的數據相關性,以防止矢量化。循環的不同迭代互相干擾,使向量化循環會產生錯誤的答案,並且自動向量化器不能證明自己沒有這樣的數據相關性「。 [源](https://msdn.microsoft.com/en-us/library/jj658585.aspx#BKMK_ReasonCode120x) – Tony

回答

-3

我認爲這是由於大量的訪問爲const變量k限制了SIMD的目的,每一個指令必須取常數變量k

+2

這顯然不是真的。 – harold

+0

重複訪問第三個函數中不可變K的情況如何?在第二個函數中重複調用'a.size()'怎麼樣? :P – hegel5000

2

我想這是一些深深內部編譯器實現的問題,像自動向量化器在什麼階段「進入」,以及當時代碼的內部表示狀態如何。當我嘗試使用MSVC2017時,它更符合人們的期望。它自動向量化update()update3(),但update2(),與線14給501的原因,這是記錄爲:

感應變量不是本地的;或上限不是循環不變的。

相關問題