2017-04-26 55 views
1

我嘗試了x86_64上的Visual Studio 2013的Auto-Vectorizer模式,我對以下內容感到有點驚訝。考慮天真代碼:info C5012:由於原因'1007'循環未並行化

static void rescale(double * __restrict out, unsigned short * __restrict in, size_t n, const double intercept, const double slope) 
{ 
    for(size_t i = 0; i < n; ++i) 
     out[i] = slope * in[i] + intercept; 
} 

Visual Studio中返回它失敗在這種簡單的例子有:

--- Analyzing function: rescale 
c:\users\malat\autovec\vec.c(18) : info C5012: loop not parallelized due to reason '1007' 

凡編譯行是(我只在SSE2興趣現在):

cl vec.c /O2 /Qpar /Qpar-report:2 

望着文檔:

引出:

其內容:

迴路感應變量或循環邊界沒有符號的32位 數(int或long)。通過更改 歸納變量的類型來解決此問題。

有沒有辦法重寫這個循環,以便自動矢量化模式被正確觸發?

我未能用一個簡單的方法來重寫代碼:

static void rescale(double * __restrict out, unsigned short * __restrict in, size_t n, const double intercept, const double slope) 
{ 
    const long first = (long)n; 
    const long secnd = n > LONG_MAX ? n - LONG_MAX : 0; 
    for(long i = 0; i < first; ++i) 
    out[i] = slope * in[i] + intercept; 
    for(long i = 0; i < secnd; ++i) 
    out[LONG_MAX+i] = slope * in[LONG_MAX+i] + intercept; 
} 

在上述情況下的Visual Studio現在報道:

--- Analyzing function: rescale 
c:\users\malat\autovec\vec.c(21) : info C5012: loop not parallelized due to reason '1000' 
c:\users\malat\autovec\vec.c(23) : info C5012: loop not parallelized due to reason '1000' 

這意味着:

檢測到的編譯器循環體中的數據依賴性。

在第二種情況下,我看不到數據依賴性。

我應該如何重寫我的初始代碼以取悅Visual Studio 2013的Auto-Vectorizer模式?

回答

1

SSE2及其前身SSE都沒有正確的指令將uint16_t -s轉換爲double-s。

in轉換成double*

+0

'gcc'似乎產生更快的東西。我需要準確地挖掘它在做什麼,但是,你是對的,我的'in'表示爲'unsigned short',可能並不簡單直接使用SSE2。 – malat

+0

@malat,AFAIR,GCC可以通過手工構建載體,填充多個XMM寄存器,然後展開幾次迭代以利用它們。 – hidefromkgb