Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 签名整数阵列的高性能比较(使用英特尔IPP库)_C++_Arrays_Performance_Comparison_Intel Ipp - Fatal编程技术网

C++ 签名整数阵列的高性能比较(使用英特尔IPP库)

C++ 签名整数阵列的高性能比较(使用英特尔IPP库),c++,arrays,performance,comparison,intel-ipp,C++,Arrays,Performance,Comparison,Intel Ipp,我们正在尝试使用不等式运算,以高性能的方式比较两个大小相等的本机有符号int值数组。当比较多个值时,true/false结果将存储在输入大小相同的char数组中,其中0x00表示false,0xff表示true 为此,我们使用“英特尔IPP”库。问题是,我们从图像和视频处理库中找到的执行此操作的函数名为ippiCompare*,它只支持类型unsigned char(Ipp8u)、signed/unsigned short(Ipp16s/Ipp16u)和float(Ipp32f)。它不直接支持签

我们正在尝试使用不等式运算,以高性能的方式比较两个大小相等的本机
有符号int
值数组。当比较多个值时,
true/false
结果将存储在输入大小相同的
char
数组中,其中
0x00
表示
false
0xff
表示
true

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

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

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

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

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

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


PS2:link for the

我以为有一条SSE指令可以比较整数。你有没有研究过可以做到这一点的内在因素?

你可以与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++;
    }
}
#包括
无效cmp(uuum128d*a、uuum128d*b、v16qi*结果、无符号计数){
for(无符号i=0;i

需要对齐的指针,一个可以被16整除的计数,当然,由于懒惰/愚蠢和可能的大量调试,我省略了一些类型转换。我没有找到packssdw/wb的内部函数,所以我只使用了我的编译器中的内置函数。

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

您是对的,对于纯内存操作,内存带宽通常是限制因素。尽管如此,即使对于简单的内存拷贝,sse指令的性能也会比“天真”方式或字符串操作好,即使只是小幅度。与简单方法相比,只有四分之一的执行单元被占用,因此超线程可能从向量操作中获益匪浅。此外,如果他有流数据,他可能会选择绕过缓存(非时态mov指令),以避免缓存污染;谢谢你的建议。无论如何,我们将使用IPP和简单的标量操作在我们正在构建的每个操作的两个版本之间运行比较测试,以确保真正的性能提升。我现在正在检查MMX操作,这似乎是实现我预期的一个好方法。我只是不确定在这种情况下多核的使用:似乎它不是“自动”完成的,对吗?不是。而且由于两个核共享一部分资源,如缓存和内存的最后一级,内存带宽可能会成为瓶颈。对于一个如此简单的例行公事来说,可能不值得付出努力。更糟糕的是,性能可能会因各种原因而受损。