c++ - 是否有 SIMD 指令来加速校验和计算?

标签 c++ checksum simd

我将不得不编写一个非常基本的校验和函数,例如:

char sum(const char * data, const int len)
{
    char sum(0);
    for (const char * end=data+len ; data<end ; ++data)
        sum += *data;
    return sum;
}

这是微不足道的。现在,我应该如何优化它? 首先,我可能应该使用一些 std::for_each 和 lambda 或类似的东西:

char sum2(const char * data, const int len)
{
    char sum(0);
    std::for_each(data, data+len, [&sum](char b){sum+=b;});
    return sum;
}

接下来,我可以使用多个线程/核心来汇总 block ,然后添加结果。我不会把它写下来,我担心创建线程(或者无论如何从池中获取它们),然后切割数组,然后分派(dispatch)所有东西等等的成本,考虑到我大部分时间都不会很好计算小数组的校验和,大部分为 10-100 字节,很少达到 1000。

但我真正想要的是较低级别的东西,一些 SIMD 东西,可以对 128b 寄存器上的字节求和,或者可能在两个寄存器之间独立地求和字节而不携带进位,或者两者兼而有之。

有这样的东西吗?

注意:这是实际的过早优化,但它很有趣,那到底是什么?

编辑:我仍然需要一种方法来汇总 SSE 寄存器中的所有字节,这比

char ptr[16];
_mm_storeu_si128((__m128i*)ptr, sum);
checksum += ptr[0] + ptr[1] + ptr[2]  + ptr[3]  + ptr[4]  + ptr[5]  + ptr[6]  + ptr[7]
          + ptr[8] + ptr[9] + ptr[10] + ptr[11] + ptr[12] + ptr[13] + ptr[14] + ptr[15];

最佳答案

是的,MMX指令集中有这样的指令,叫做“Packed ADD”:

  • _mm_add_pi8在 Visual C++ 中
  • __builtin_ia32_paddb 在 gcc 中

在 SSE2 指令集中:

  • _mm_add_epi8在 Visual C++ 中
  • __builtin_ia32_paddb128 在 gcc 中

编辑:添加部分和的更快方法:

__m128i sums;

sums = _mm_add_epi8(sums, _mm_srli_si128(sums, 1));
sums = _mm_add_epi8(sums, _mm_srli_si128(sums, 2));
sums = _mm_add_epi8(sums, _mm_srli_si128(sums, 4));
sums = _mm_add_epi8(sums, _mm_srli_si128(sums, 8));
checksum += _mm_cvtsi128_si32(sums);

关于c++ - 是否有 SIMD 指令来加速校验和计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6671929/

相关文章:

c++ - 英特尔 SIMD 指令加速

c++ - SIMD 和压缩和标量 double 之间的区别

c++ - 如何调试用 C++ 编写的内核?

java - Ant/checksum : How to generate one . md5 文件用于多个文件(导致 md5 文件包含多行)

ios - iOS 中的 malloc 校验和逻辑是什么?

windows - 在 windows 上计算文件夹的校验和并在 linux 上验证

c# - 硬件SIMD解析可提高C#性能

使用 Boost 库的 C++ 线程

c++ - 指针和拷贝

c++ - opencv中的镜像