我们尝试使用不等式运算来比较两个大小相同的signed int
值的原始数组,<,< =,>和> =,以高性能的方式。在比较多个值时,true/false
结果会放在输入大小相同的char
数组中,其中0x00
表示false
和0xff
表示true
。
为实现这一目标,我们正在使用英特尔IPP库。问题是我们发现从图像和视频处理库执行此操作(名为ippiCompare_*
)的函数仅支持unsigned char
(Ipp8u
),signed/unsigned short
类型(Ipp16s/Ipp16u
)和float
(Ipp32f
)。它不直接支持signed int
(Ipp32s
)
我(仅)设想两种可能的解决方法:
将数组转换为其中一个直接支持的类型,并在更多步骤中执行比较(它将成为两倍大小的短数组或大小为四倍的char数组)并合并中间结果。< / p>
使用另一个函数直接支持来自IPP的signed int
数组或其他可以在性能方面做同等事情的库。
但可能还有其他创造性方法......所以我请你帮忙! :)
PS:使用英特尔IPP的优势在于大型阵列的性能提升:它同时使用多值处理器功能和多个核心(可能还有更多技巧)。如此简单的循环解决方案不会像快速AFAIK那样做。 的链接答案 0 :(得分:1)
我认为有一个SSE指令可以比较整数。你有没有看过可以做到这一点的内在函数?
答案 1 :(得分:1)
您可以与PCMPEQD进行比较,然后是PACKUSDW和PACKUSWB。这将是
#include <emmintrin.h>
void cmp(__m128d* a, __m128d* b, v16qi* result, unsigned count) {
for (unsigned i=0; i < count/16; ++i) {
__m128d result0 = _mm_cmpeq_pd(a[0], b[0]); // each line compares 4 integers
__m128d result1 = _mm_cmpeq_pd(a[1], b[1]);
__m128d result2 = _mm_cmpeq_pd(a[2], b[2]);
__m128d result3 = _mm_cmpeq_pd(a[3], b[3]);
a += 4; b+= 4;
v8hi wresult0 = __builtin_ia32_packssdw(result0, result1); //pack 2*4 integer results into 8 words
v8hi wresult1 = __builtin_ia32_packssdw(result0, result1);
*result = __builtin_ia32_packsswb(wresult0, wresult1); //pack 2*8 word results into 16 bytes
result++;
}
}
需要对齐指针,一个可被16整除的计数,一些由于懒惰/愚蠢而省略的类型转换,当然可能还有很多调试。我没有找到packssdw / wb的内在函数,所以我只使用了编译器中的内置函数。
答案 2 :(得分:0)
开箱即用:您确定这是性能问题吗?除非您的数据集适合L1缓存,否则您将限制缓存填充以及您在比较操作上花费的实际周期(即使以最简单的方式完成,也很难慢)不可能是限制性的。