代码之家  ›  专栏  ›  技术社区  ›  Alexey Malistov

如何优化周期?

  •  6
  • Alexey Malistov  · 技术社区  · 14 年前

    我有以下瓶颈功能。

    typedef unsigned char byte;
    void CompareArrays(const byte * p1Start, const byte * p1End, const byte * p2, byte * p3)
    {
         const byte b1 = 128-30;
         const byte b2 = 128+30;
         for (const byte * p1 = p1Start; p1 != p1End; ++p1, ++p2, ++p3) {
            *p3 = (*p1 < *p2 ) ? b1 : b2;
        }
    }
    

    我想换一个 C++ 使用SSE2内部函数编码。我试过了 _mm_cmpgt_epi8 但它使用了有符号的比较。我需要无符号比较。

    有什么技巧(SSE,SSE2,SSSE3)来解决我的问题吗?

    注: 在这种情况下,我不想使用多线程。

    6 回复  |  直到 11 年前
        1
  •  9
  •   Paul R    14 年前

    与其用带符号的值进行偏移来使它们无符号化,一种更有效的方法是执行以下操作:

    • 使用 _mm_min_epu8 得到p1,p2的无符号最小值
    • 将此最小值与p2相等,使用 _mm_cmpeq_epi8
    • 对于p1<p2的元素,结果掩码现在将为0x00;对于p1>=p2的元素,结果掩码将为0xff。
    • 你现在可以用这个面具 _mm_or_si128 _mm_andc_si128 选择适当的b1/b2值

    请注意,这总共是4条指令,与使用偏移+有符号比较方法的5条指令相比。

        2
  •  2
  •   BЈовић    14 年前

    您可以从数字中减去127,然后使用

        3
  •  2
  •   Crashworks    14 年前

    是的,这可以在simd中完成,但是制作这个面具需要几个步骤。

    我想Ruslik做对了。您希望用0x80对每个组件执行XOR,以翻转有符号和无符号比较的意义。MyxxOrsi-Si128 PXOR )得到这样的结果——在将掩码加载到simd寄存器之前,需要在某处创建一个静态char数组。然后mm_cmpgt_epi8给你一个蒙版,你可以使用一个按位和(例如 _mm_and_si128 )进行蒙面移动。

        4
  •  1
  •   Alex F    14 年前

    是的,SSE在这里不工作。 您可以通过使用OpenMP提高多核计算机上的代码性能:

    void CompareArrays(const byte * p1Start, const byte * p1End, const byte * p2, byte * p3)
    {
         const byte b1 = 128-30;
         const byte b2 = 128+30;
    
         int n = p1End - p1Start;
         #pragma omp parallel for
         for (int i = 0; i < n; ++p1, ++i) 
         {
            p3[i] = (p1[i] < p2[i]) ? b1 : b2;
         }
    }
    
        5
  •  -1
  •   T Wu    11 年前

    不幸的是,上面的许多答案都是错误的。假设一个3位字:

    无符号:4 5 6 7 0 1 2 3==有符号:-4-3-2-1 0 1 2 3(位:100 101 110 111 000 001 011)

    保罗R的方法不正确。假设我们想知道3>2。Min(3,2)==2,这表示是,所以方法在这里有效。现在假设我们想知道是否7>2。在有符号表示中,值7是-1,因此min(-1,2)=-1,这错误地表明7不大于2无符号。

    安德烈的方法也不正确。假设我们想知道是7>2,还是a=7,b=2。在有符号表示中,值7为-1,因此第一个术语(a>b)失败,方法建议7不大于2。

    然而,bjobnh的方法是正确的,经Alexey修正。只需从值中减去2^(n-1),其中n是位数。在这种情况下,我们将减去4得到新的对应值:

    旧的有符号:-4-3-2-1 0 1 2 3=>新的有符号:0 1 2 3-4-3-2-1==新的无符号0 1 2 3 4 5 6 7。

    换句话说,无符号_大于(a,b)等于有符号_大于(a-2^(n-1),b-2^(n-1))。

        6
  •  -3
  •   Alexander Solonsky    14 年前

    使用pcmpeqb,成为您的动力。

    推荐文章