【问题标题】:How multiply convolutional core of 3x3 and an image如何将 3x3 的卷积核与图像相乘
【发布时间】:2018-10-28 23:53:30
【问题描述】:

有一个 3x3 的卷积核和一个由整数值像素数组表示的图像。

一个卷积核表示如下:

//compound convolutional kernels
//                                | 1, 0,  1|
// convolutional kernel H = src x | 0, 0,  0|
//                                |-1, 0, -1|

//                                | 1, 0, -1|
// convolutional kernel V = src x | 0, 0,  0|
//                                | 1, 0, -1|

卷积核 = 核 H + 核 V

for(int inc=0; inc<height-2; inc++)
{
    //loaded 3 lines into memory
    str1_16pxs = _mm_loadu_si128((__m128i*)(src_all_str));
    str2_16pxs = _mm_loadu_si128((__m128i*)(src2_all_str));
    str3_16pxs = _mm_loadu_si128((__m128i*)(src3_all_str));

    //packing 16bit
    str1_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str1_16pxs);
    str2_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str2_16pxs);
    str3_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str3_16pxs);

//---!
        //there is we make the first convolution for 8px's
        //... How ???
//---

    //summ 1st 8to16 vertical registers
    sum1_str12_vert_16pxs_pack1st_8to16  = _mm_add_epi16(str1_16pxs_pack1st_8to16,           str2_16pxs_pack1st_8to16);
    sum1_str123_vert_16pxs_pack1st_8to16 = _mm_add_epi16(sum1_str12_vert_16pxs_pack1st_8to16,str3_16pxs_pack1st_8to16);

    for(int jnc=0; jnc<(width >> 4); jnc++)
    {
        str1_16pxs_plus_8pxs = _mm_srli_si128(str1_16pxs, 8);
        str2_16pxs_plus_8pxs = _mm_srli_si128(str2_16pxs, 8);
        str3_16pxs_plus_8pxs = _mm_srli_si128(str3_16pxs, 8);

        //pack 2nd 8to16 registers (+8px's)
        str1_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str1_16pxs_plus_8pxs);
        str2_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str2_16pxs_plus_8pxs);
        str3_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str3_16pxs_plus_8pxs);

//---!
            //do convolution for the remaining 8px's and so on until the end of the read line
            //... How ???
//---

        //summ vertic 8to16 registers
        sum1_str12_vert_16pxs_pack2nd_8to16  = _mm_add_epi16(str1_16pxs_pack2nd_8to16,           str2_16pxs_pack2nd_8to16);
        sum1_str123_vert_16pxs_pack2nd_8to16 = _mm_add_epi16(sum1_str12_vert_16pxs_pack2nd_8to16,str3_16pxs_pack2nd_8to16);

//---!4     loading next 16 px's
        src_all_str += 16;
        src2_all_str += 16;
        src3_all_str += 16;

        //...

        _mm_store_si128((__m128i*)(dst_all_str), res);
        dst_all_str += 8;

    }//for(jnc)

}//for(inc)

【问题讨论】:

  • 问题是什么?奇怪的中间部分是什么?
  • 查看代码://---! //这里是我们为 8px 的第一个卷积 //... 怎么样 ??? //---
  • 代码是为了代码。问题和描述你有什么/你想要什么应该放在文本中。
  • 请阅读How to Ask,尤其是关于作业问题的链接。
  • 你怎么解释?有一个由整数值表示的像素数组。有一个卷积3x3的核心。在我从数组中读取三行来处理卷积核之后,这是必要的。如何处理整数值的卷积数组的核心我不知道。在“如何?”我指明了要进行此操作的地点。

标签: c c++11 sse simd intrinsics


【解决方案1】:

所以,示例代码:

void SSEcode_Conv3x3 (unsigned char *src, int width, int height, short *dst) 
{
// Assert that width is a multiple of 16
if (width & 0xF) return;

unsigned char* src_line1 = src;
unsigned char* src_line3 = src + 2 * width;

__m128i zero = _mm_setzero_si128();

for (int i = 0; i < height - 2; i++) 
{
    __m128i line1 = _mm_load_si128((__m128i*)src_line1);
    __m128i line3 = _mm_load_si128((__m128i*)src_line3);
     for (int j = 0; j < width / 16 - 1; j++)
     {
        src_line1 += 16;
        src_line3 += 16;

        __m128i line1next = _mm_load_si128((__m128i*)src_line1);
        __m128i line3next = _mm_load_si128((__m128i*)src_line3);

       //blablabla
#ifdef USE_CORE_H
_mm_add_epi16
_mm_add_epi16
_mm_sub_epi16
#endif
       //blablabla

       _mm_store_si128((__m128i*)(dst + 8), res);
       line1 = line1next;
       line3 = line3next;

       dst += 16;
     }//for (j)

     src_line1 += 16;
     src_line3 += 16;

     //blablabla

     _mm_store_si128((__m128i*)(dst + 8), res);
     dst += 16;
}//for (i)

}

编写代码花了很长时间。 我是新人,所以很可惜一个精通CE的人没有帮助intrisics。:(

【讨论】:

  • 您是否遇到了复制/粘贴错误?你的代码甚至不会编译你有 _mm_add_epi16 在一行本身没有参数。
  • Peter Cordes 这是示例代码。)代码占用 342 行。
  • 那么这不是您问题的答案。为什么你甚至在没有链接到你的实际实现的情况下发布这个?对于在寻找 3x3 图像卷积时发现此问答的任何人来说,这根本没有用。
  • Peter Cordes,例如,我可以写一个关于做什么的抽象解释。
  • 请使用您问题上的编辑链接添加其他信息。 Post Answer 按钮应仅用于问题的完整答案。 - From Review
猜你喜欢
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 2016-05-27
  • 2013-12-17
相关资源
最近更新 更多