c++ - signed int 数组的高性能比较(使用英特尔 IPP 库)

标签 c++ arrays performance comparison intel-ipp

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

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

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

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

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

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

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

PS2:ippiCompare_* doc 的链接

最佳答案

您可以使用 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 的内部函数,所以我只使用了编译器中的内置函数。

关于c++ - signed int 数组的高性能比较(使用英特尔 IPP 库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1580063/

相关文章:

c++ - 如何在 Windows 公用文件对话框中显示 API 填充的虚拟文件夹

java - 字符串数组的元素无法与字符串进行比较

java - 使用 ArrayList 排序进行图形绘制排序

sql - 性能差异大 : Using sysdate vs using pre-formatted date

c++ - Access violation reading location 尝试获取系统时间时

c++ - 模板的正确语法

c++ - 使用未声明的标识符 'Token'

android - 具有多项选择的 ExpandableListView 将所选项目保存到数组中

javascript - 请解释这个 Javascript 怪癖

jquery - 查找嵌套表格单元格内容 - jquery 查询性能