2017-05-04 38 views
0

我有這樣的功能代碼:未對齊的對齊指針上的訪問?

bool interpolate(const Mat &im, float ofsx, float ofsy, float a11, float a12, float a21, float a22, Mat &res) 
{   
    bool ret = false; 
    // input size (-1 for the safe bilinear interpolation) 
    const int width = im.cols-1; 
    const int height = im.rows-1; 
    // output size 
    const int halfWidth = res.cols >> 1; 
    const int halfHeight = res.rows >> 1; 
    float *out = res.ptr<float>(0); 
    const float *imptr = im.ptr<float>(0); 
    for (int j=-halfHeight; j<=halfHeight; ++j) 
    { 
     const float rx = ofsx + j * a12; 
     const float ry = ofsy + j * a22; 
     #pragma omp simd 
     for(int i=-halfWidth; i<=halfWidth; ++i, out++) 
     { 
     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; 
      int rowOffset = y*im.cols; 
      int rowOffset1 = (y+1)*im.cols; 
      // bilinear interpolation 
      *out = 
       (1.0f - wy) * ((1.0f - wx) * imptr[rowOffset+x] + wx * imptr[rowOffset+x+1]) + 
       (  wy) * ((1.0f - wx) * imptr[rowOffset1+x] + wx * imptr[rowOffset1+x+1]); 
     } else { 
      *out = 0; 
      ret = true; // touching boundary of the input    
     } 
     } 
    } 
    return ret; 
} 

這是與icpc編譯代碼部分,以下選項:

INTEL_OPT=-O3 -simd -xCORE-AVX2 -parallel -qopenmp -fargument-noalias -ansi-alias -no-prec-div -fp-model fast=2 -fma -align -finline-functions 
INTEL_PROFILE=-g -qopt-report=5 -Bdynamic -shared-intel -debug inline-debug-info -qopenmp-link dynamic -parallel-source-info=2 -ldl 

在優化報告文件(.optr)有這些行:

remark #15389: vectorization support: reference *out has unaligned access [ /home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Descriptors/hesaff/helpers.cpp(259,14) ] 
    remark #15389: vectorization support: reference *out has unaligned access [ /home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Descriptors/hesaff/helpers.cpp(263,14) ] 
    remark #15389: vectorization support: reference *out has unaligned access [ /home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Descriptors/hesaff/helpers.cpp(263,14) ] 

線259和263是其中明顯out值被改變的人。

據我所知,這意味着out是unaligned(更多信息在這裏[https://software.intel.com/en-us/articles/fdiag15126]here)。

但是,這已經很奇怪,因爲我發現它here,cv::Mat對象已經對齊。但是,這可能是合法的,因爲編譯器會不知道對齊的...... 如果我專門分配out作爲對齊指針,如果我添加下面一行然而出現的消息:

out = (float*) _mm_malloc(res.cols*res.rows*sizeof(float), 32); 

這應該是足夠的告訴編譯器數據是對齊的。我錯了嗎?否則,我怎麼能告訴它,out已經對齊?

回答

0

編譯器看到out++。它不能保持對齊。

(也就是說,它仍然是float*訪問對齊,但消息指SIMD矢量這需要更嚴格對齊)

+0

謝謝您的回答。所以假設我使用的是一臺可以同時處理8個浮點元素的AVX2機器,我應該在一個迭代循環中計算8個值,然後在'for'子句中執行'out + = 8'嗎?如果我沒有錯,這是循環展開,這是由編譯器自動完成的。我錯過了什麼? – justHelloWorld

+0

(你可以看看[this](http://stackoverflow.com/questions/43778590/ineffective-remainder-loop-in-my-code)的問題嗎?) – justHelloWorld