繁体   English   中英

如何优化循环?

[英]How to optimize a cycle?

我有以下瓶颈功能。

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;
    }
}

我想用SSE2内部函数替换C++代码。 我尝试了_mm_cmpgt_epi8但它使用了签名比较。 我需要无符号比较。

是否有任何技巧(SSE,SSE2,SSSE3)来解决我的问题?

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

而不是抵消您的签名值以使其无符号,更有效的方法是执行以下操作:

  • 使用_mm_min_epu8获取p1,p2的无符号最小值
  • 使用_mm_cmpeq_epi8将此min与p2进行_mm_cmpeq_epi8
  • 对于p1 <p2的元素,结果掩码现在为0x00,对于p1> = p2的元素,结果掩码为0xff
  • 你现在可以使用这个掩码与_mm_or_si128_mm_andc_si128来选择合适的b1 / b2值

请注意,总共有4条指令,而使用offset + signed比较方法则为5条指令。

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

是的,这可以在SIMD中完成,但制作蒙版需要几个步骤。

我想,鲁斯利克做对了。 您希望使用0x80对每个组件进行xor以翻转有符号和无符号比较的意义。 _mm_xor_si128( PXOR )可以解决这个问题 - 在将掩码加载到SIMD寄存器之前,您需要在某处创建掩码作为静态char数组。 然后_mm_cmpgt_epi8为您提供一个掩码,您可以使用按位AND(例如_mm_and_si128 )执行蒙版移动。

是的,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;
     }
}

不幸的是,上面的许多答案都是不正确的。 我们假设一个3位字:

unsigned:4 5 6 7 0 1 2 3 == signed:-4 -3 -2 -1 0 1 2 3(位:100 101 110 111 000 001 010 011)

Paul R的方法不正确。 假设我们想知道3> 2.min(3,2)== 2,这表明是,所以这个方法在这里工作。 现在假设我们想知道是否7> 2.签名表示中的值7是-1,所以min(-1,2)== -1,这表明7不大于2 unsigned。

安德烈的方法也不正确。 假设我们想要知道7> 2,或a = 7,并且b = 2.签名表示中的值7为-1,因此第一项(a> b)失败,并且该方法表明7不大于比2。

然而,由Alexey纠正的BJobnh的方法是正确的。 只需从值中减去2 ^(n-1),其中n是位数。 在这种情况下,我们将减去4以获得新的相应值:

old signed:-4 -3 -2 -1 0 1 2 3 => new signed:0 1 2 3 -4 -3 -2 -1 == new unsigned 0 1 2 3 4 5 6 7。

换句话说,unsigned_greater_than(a,b)等同于signed_greater_than(a-2 ^(n-1),b-2 ^(n-1))。

使用pcmpeqb并成为你的力量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM