2

我们正在尝试以signed int高性能的方式使用不等式操作 <、<=、> 和 >= 来比较两个大小相同的原生值数组。由于比较了许多值,true/false结果将存储在char与输入大小相同的数组中,其中0x00均值false0xff均值true

为此,我们使用了英特尔 IPP 库。问题是我们ippiCompare_*从图像和视频处理库中找到的执行此操作的函数名为 ,仅支持类型unsigned char( Ipp8u)、signed/unsigned short( Ipp16s/Ipp16u) 和float( Ipp32f)。它不直接支持signed int( Ipp32s)

我(仅)设想了两种可能的解决方法:

  • 将数组转换为直接支持的类型之一并在更多步骤中执行比较(它将变成大小两倍的短数组或大小四倍的 char 数组)并合并中间结果。

  • 使用另一个函数直接支持signed int来自 IPP 或另一个库的数组,这些函数可以在性能方面做一些等效的事情。

但可能还有其他创造性的方式......所以我请你帮忙!:)

PS:使用英特尔 IPP 的优势在于大型阵列的性能提升:它同时使用多值处理器功能和多个内核(可能还有更多技巧)。如此简单的循环解决方案不会像AFAIK那样快。

PS2:ippiCompare_* 文档的链接

4

3 回答 3

1

我认为有一个 SSE 指令可以比较整数。您是否研究过可以做到这一点的内在函数?

于 2009-10-16T20:49:57.890 回答
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 的内在函数,所以我只使用了编译器中的内置函数。

于 2009-10-16T20:54:49.690 回答
0

开箱即用:您确定这是性能问题吗?除非您的数据集适合 L1 缓存,否则您的缓存填充将受到限制,并且您在比较操作上花费的实际周期(即使以最简单的方式完成也不会很慢)不可能受到限制。

于 2009-10-16T22:03:14.207 回答