首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何使用SIMD优化for循环的计算?

如何使用SIMD优化for循环的计算?
EN

Stack Overflow用户
提问于 2019-05-09 20:04:21
回答 1查看 247关注 0票数 1

我正在尝试使用Neon SIMD在ODROID XU4 ARM平台上加速一个立体匹配算法。对于这个puropose,我使用openMp的编译指示。

代码语言:javascript
运行
复制
 void StereoMatch:: sadCol(uint8_t* leftRank,uint8_t* rightRank,const int SAD_WIDTH,const int SAD_WIDTH_STEP, const int imgWidth,int j, int d , uint16_t* cost) 
  {

   uint16_t sum = 0;
   int n = 0;
   int m =0;
      for ( n = 0; n < SAD_WIDTH+1; n++)
      {

     #pragma omp simd
     for(  m = 0; m< SAD_WIDTH_STEP; m = m + imgWidth ) 
         {


        sum += abs(leftRank[j+m+n]-rightRank[j+m+n-d]);

         };
         cost[n] = sum;
         sum = 0;



  };

我对SIMD和openMp比较陌生,我知道在代码中使用SIMD杂注将指导编译器向量化减法,但当我执行代码时,我注意到没有区别。我应该向我的代码添加什么才能将其矢量化?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-17 23:53:31

正如评论中所说,ARM-Neon有一条指令,可以直接做你想做的事情,即计算无符号字节的绝对差,并将其累加为无符号短整型。

假设使用SAD_WIDTH+1==8,下面是一个使用内部函数的非常简单的实现(基于@nemequ的简化版本):

代码语言:javascript
运行
复制
void sadCol(uint8_t* leftRank,
            uint8_t* rightRank,
            int j,
            int d ,
            uint16_t* cost) {
    const int SAD_WIDTH = 7;
    const int imgWidth = 320;
    const int SAD_WIDTH_STEP = SAD_WIDTH * imgWidth;

    uint16x8_t cost_8 = {0};
    for(int m = 0; m < SAD_WIDTH_STEP; m = m + imgWidth )  {
        cost_8 = vabal_u8(cost_8, vld1_u8(&leftRank[j+m]), vld1_u8(&rightRank[j+m-d]));
    };
    vst1q_u16(cost, cost_8);
};

vld1_u8加载8个连续字节,vabal_u8计算绝对差值并将其累加到第一个寄存器。最后,vst1q_u16将寄存器存储到内存中。

您可以轻松地设置imgWidthSAD_WIDTH_STEP函数参数。如果SAD_WIDTH+1是8的不同倍数,您可以为此编写另一个循环。

我手头没有ARM平台来测试它,但是“它可以编译”:https://godbolt.org/z/vPqiYI (在我看来,程序集看起来很好)。如果您使用-O3进行优化,则gcc将展开循环。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56059038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档