我是否必须对齐数据才能对此功能进行矢量化?

时间:2017-04-26 12:46:09

标签: c++ parallel-processing vectorization simd

我有这个功能,英特尔顾问强烈建议它进行矢量化:

void SIFTDescriptor::samplePatch(float *vec)
{
   for (int r = 0; r < par.patchSize; ++r)
   {
      const int br0 = par.spatialBins * bin0[r]; const float wr0 = w0[r];
      const int br1 = par.spatialBins * bin1[r]; const float wr1 = w1[r];
      for (int c = 0; c < par.patchSize; ++c)
      {
         const float val = mask.at<float>(r,c) * grad.at<float>(r,c);

         const int bc0 = bin0[c];
         const float wc0 = w0[c]*val;
         const int bc1 = bin1[c];
         const float wc1 = w1[c]*val;

         // ori from atan2 is in range <-pi,pi> so add 2*pi to be surely above zero
         const float o = float(par.orientationBins)*(ori.at<float>(r,c) + 2*M_PI)/(2*M_PI);

         int   bo0 = (int)o;
         const float wo1 =  o - bo0;
         bo0 %= par.orientationBins;

         int   bo1 = (bo0+1) % par.orientationBins;
         const float wo0 = 1.0f - wo1;

         // add to corresponding 8 vec...
         if (wr0*wc0>0) {
             vec[br0+bc0+bo0] += wr0*wc0 * wo0;
             vec[br0+bc0+bo1] += wr0*wc0 * wo1;
         }
         if (wr0*wc1>0) {
             vec[br0+bc1+bo0] += wr0*wc1 * wo0;
             vec[br0+bc1+bo1] += wr0*wc1 * wo1;
         }
         if (wr1*wc0>0) {
             vec[br1+bc0+bo0] += wr1*wc0 * wo0;
             vec[br1+bc0+bo1] += wr1*wc0 * wo1;
         }
         if (wr1*wc0>0) {
             vec[br1+bc1+bo0] += wr1*wc0 * wo0;
             vec[br1+bc1+bo1] += wr1*wc0 * wo1;
         }
      }
   }
}

我使用带有以下选项的intel编译器:

INTEL_OPT=-O3 -ipo -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 -ldl

但是,英特尔顾问告诉我,在:

中有两个Read-After-Write依赖项
 vec[br0+bc0+bo0] += wr0*wc0 * wo0;

 vec[br1+bc0+bo0] += wr1*wc0 * wo0;

现在,我是一个非常初学的simd,根据我的理解,我必须编写SSE / AVX2 / AVX-512指令来解决这种依赖。例如,我发现了this问题,其中解释了如何在阵列单元格中保存累积总和。这与this有所不同,因为我想将累积结果的结果保存在数组的元素(vec[something]而不是像result这样的标量变量中。)

然而,在第二个问题的答案中,它解释了为了使用该代码,我们需要对齐数据。由于vec是指向cv::Mat对象的指针,因此我并不认为数据是对齐的。

this回答中有人争辩说询问对齐数据是否对我的问题是必要的。换句话说,我担心自己陷入了XY问题,在那里我专注于将数据对齐在哪里(也许)实际上并不需要(特别是因为我&#39 ; ma simd初学者,我害怕过度思考)。

注意:我正在使用兼容AVX2的机器,我计划将其移至AVX-512机器。

0 个答案:

没有答案