2017-03-31 80 views
2

我從來沒有寫過SSE優化的彙編代碼,所以很抱歉,如果這是一個菜鳥問題。在this aritcle解釋瞭如何使用條件語句矢量化for。然而,我的代碼(從here採取)的形式爲:是否可以使用SSE爲此嵌套進行矢量化?

for (int j=-halfHeight; j<=halfHeight; ++j) 
    { 
     for(int i=-halfWidth; i<=halfWidth; ++i) 
     { 
     const float rx = ofsx + j * a12; 
     const float ry = ofsy + j * a22; 
     float wx = rx + i * a11; 
     float wy = ry + i * a21; 
     const int x = (int) floor(wx); 
     const int y = (int) floor(wy); 
     if (x >= 0 && y >= 0 && x < width && y < height) 
     { 
      // compute weights 
      wx -= x; wy -= y; 
      // bilinear interpolation 
      *out++ = 
       (1.0f - wy) * ((1.0f - wx) * im.at<float>(y,x) + wx * im.at<float>(y,x+1)) + 
       (  wy) * ((1.0f - wx) * im.at<float>(y+1,x) + wx * im.at<float>(y+1,x+1)); 
     } else { 
      *out++ = 0; 
     } 
     } 
    } 

所以,從我的理解,有與鏈接的文章的幾個不同之處:

  1. 在這裏,我們有一個嵌套for:我在vectroization中總是看到一個級別for,從未見過嵌套循環
  2. if條件基於標量值(x和y)而不是數組:我怎樣才能使鏈接的示例適應此?
  3. out指數不是基於ij(所以它不是out[i]out[j]):我怎麼能以這種方式填補out

特別我很困惑,因爲for索引始終用作數組索引,而在這裏被用於計算變量而矢量由週期遞增週期

我使用icpc-O3 -xCORE-AVX2 -qopt-report=5和一堆其他優化標誌。根據英特爾顧問,這是不是矢量化,並使用#pragma omp simd生成warning #15552: loop was not vectorized with "simd"

+1

你使用哪種編譯器?你有沒有確認你的編譯器還沒有爲你自動矢量化? – Jonas

+0

@Jonas感謝您的評論。請看看我更新的問題 – justHelloWorld

+1

與您以前的問題非常相似http://stackoverflow.com/questions/43136182/compiler-doesnt-vectorize-even-with-simd-directive有什麼變化? –

回答

4

雙線性插值是一個相當棘手的操作矢量化,我不會嘗試它爲您的第一個SSE技巧。問題是你需要獲取的值不是很好的排序。有時會重複,有時會跳過。好消息是,內插圖像是一種常見操作,並且您很可能會發現一個預先編寫的庫來執行此操作,如OpenCV

remap()始終是一個不錯的選擇。只需構建兩個表示每個像素的分數源位置的wx和wy數組,並讓remap()進行插值。

但是,在這種情況下,它看起來像仿射變換。也就是說,分數源像素通過2x3矩陣乘法與源像素相關。這是偏移量和a11/a12/a21/a22變量。 OpenCV有這樣的轉變。請在此處閱讀:http://docs.opencv.org/3.1.0/d4/d61/tutorial_warp_affine.html

您只需將輸入變量映射到矩陣形式並調用仿射變換即可。

+0

非常感謝您的答案。我想我有點理解你解釋的過程,但是我很困惑這些函數是如何被調用的。我知道這有點不正確,但是請您詳細寫下解決方案嗎? – justHelloWorld

+0

你能幫我解決嗎? – justHelloWorld

+0

我提供的教程非常詳細地介紹了這一點。我建議閱讀教程。如果在此之後您仍然有問題,請使用您的新詞彙和技能發佈一個新問題。 – Peter