将大型char8的c数组转换为short16的最快方法是什么?

Ngoc Khanh Nguyen

我的原始数据是一堆c数组(长度为1000000的char(无符号)char(8位)。我想将它们加在一起(矢量加法),遵循以下代码中的规则。结果:(无符号)short(16位)的c数组。

我已经阅读了所有SSE和AVX / AVX2,但有一个类似的调用,即多个2个256位寄存器。前4个32位将相乘,每对32位的结果是一个64位,将适合256个寄存器。(_mm256_mul_epi32,_mm256_mul_epu32)

Firgure

https://www.codeproject.com/Articles/874396/Crunching-Numbers-with-AVX-and-AVX

样例代码:

static inline void adder(uint16_t *canvas, uint8_t *addon, uint64_t count)
{
    for (uint64_t i=0; i<count; i++)
        canvas[i] += static_cast<uint16_t>(addon[i]);
}

谢谢

迈克·藤

添加到@wim答案(这是一个很好的答案)并考虑@Bathsheba的注释,值得相信编译器还要检查编译器的输出以了解如何执行此操作并检查其在执行您的操作时是否值得d想要。通过Godbolt(适用于msvc,gcc和clang)运行经过稍微修改的代码版本会带来一些不完美的答案。

如果您将自己限制为SSE2,并且低于此答案的假设(以及我测试的内容),则尤其如此。

所有编译器都对代码进行矢量化处理和展开处理,并用于punpcklbwuint8_ts '解压缩为s uint16_t',然后运行SIMD添加和保存。很好 但是,MSVC倾向于不必要地在内部循环中溢出,而clang仅使用punpcklbw而不是clang punpckhbw这意味着它将两次加载源数据。GCC正确设置了SIMD零件,但循环约束的开销较高。

因此,从理论上讲,如果您想改进这些版本,则可以使用类似于以下内容的内部函数来滚动自己的版本:

static inline void adder2(uint16_t *canvas, uint8_t *addon, uint64_t count)
{
    uint64_t count32 = (count / 32) * 32;
    __m128i zero = _mm_set_epi32(0, 0, 0, 0);
    uint64_t i = 0;
    for (; i < count32; i+= 32)
    {
        uint8_t* addonAddress = (addon + i);

        // Load data 32 bytes at a time and widen the input
        // to `uint16_t`'sinto 4 temp xmm reigsters.
        __m128i input = _mm_loadu_si128((__m128i*)(addonAddress + 0));
        __m128i temp1 = _mm_unpacklo_epi8(input, zero);
        __m128i temp2 = _mm_unpackhi_epi8(input, zero);
        __m128i input2 = _mm_loadu_si128((__m128i*)(addonAddress + 16));
        __m128i temp3 = _mm_unpacklo_epi8(input2, zero);
        __m128i temp4 = _mm_unpackhi_epi8(input2, zero);

        // Load data we need to update
        uint16_t* canvasAddress = (canvas + i);
        __m128i canvas1 = _mm_loadu_si128((__m128i*)(canvasAddress + 0));
        __m128i canvas2 = _mm_loadu_si128((__m128i*)(canvasAddress + 8));
        __m128i canvas3 = _mm_loadu_si128((__m128i*)(canvasAddress + 16));
        __m128i canvas4 = _mm_loadu_si128((__m128i*)(canvasAddress + 24));

        // Update the values
        __m128i output1 = _mm_add_epi16(canvas1, temp1);
        __m128i output2 = _mm_add_epi16(canvas2, temp2);
        __m128i output3 = _mm_add_epi16(canvas3, temp3);
        __m128i output4 = _mm_add_epi16(canvas4, temp4);

        // Store the values
        _mm_storeu_si128((__m128i*)(canvasAddress + 0), output1);
        _mm_storeu_si128((__m128i*)(canvasAddress + 8), output2);
        _mm_storeu_si128((__m128i*)(canvasAddress + 16), output3);
        _mm_storeu_si128((__m128i*)(canvasAddress + 24), output4);
    }

    // Mop up
    for (; i<count; i++)
        canvas[i] += static_cast<uint16_t>(addon[i]);
}

检查输出结果,它绝对比gcc / clang / msvc更好。因此,如果您想获得perf的绝对最后一滴(并具有固定的体系结构),则可能会出现上述情况。但是,这是一个很小的改进,因为编译器已经可以很好地处理此问题,因此我实际上建议不要这样做,而应该信任编译器。

如果您确实认为可以改善编译器,请记住始终进行测试和配置文件以确保您确实是。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将int转换为char的最快方法是什么

来自分类Dev

将数组短转换为char的最快方法

来自分类Dev

将 imageURL 从 Firebase 转换为 UIImage 的最快方法是什么?

来自分类Dev

将具有10k .txt文件的文件夹转换为数组的最快方法是什么(python)

来自分类Dev

在javascript中将json的字段转换为数组的最快方法是什么?

来自分类Dev

在PHP中将对象转换为数组的最快方法是什么?

来自分类Dev

将char *转换为uint8_t的数组(c)

来自分类Dev

将IndexSet转换为int数组的最佳方法是什么?

来自分类Dev

SAS:将二进制压缩的数据集转换为使用 char 压缩的数据集的最快方法是什么,反之亦然?

来自分类Dev

使用JS或PHP将html转换为pdf的最快方法是什么?

来自分类Dev

检查char数组中前导字符的最快方法是什么?

来自分类Javascript

在JavaScript中将String转换为Number的最快方法是什么?

来自分类Dev

将char转换为short

来自分类Dev

将 char* 转换为 short*

来自分类Dev

将拥有字段的类的列表转换成多个数组的最快方法是什么?--

来自分类Dev

在C ++中将十六进制转换为整数的最快方法是什么?

来自分类Java

使用Java 8将字符串数组转换为int数组的最简单方法是什么?

来自分类Dev

转换数组字母数字的每个成员的最快方法是什么?

来自分类Dev

将 char 数组转换为 uint16_t 数组 C/C++

来自分类Dev

在C中将unsigned char数组转换为signed short

来自分类Javascript

将JavaScript NodeList转换为数组的最快方法?

来自分类Dev

将图像转换为字节数组的最快方法

来自分类Dev

将数组转换为多行字符串的最快方法

来自分类Dev

将数值表值转换为字符数组的最快方法

来自分类Dev

将元素追加到数组的最快方法是什么?

来自分类Dev

将 CSV 文件从 UTF-16 制表符转换为 UTF-8-SIG 逗号的最快方法

来自分类Dev

将C char数组转换为String

来自分类Dev

将数组转换为对象数组(包括数组条目作为对象键)的最佳方法是什么?

来自分类Dev

对大型字节数组进行排序和解包的最快方法是什么?

Related 相关文章

  1. 1

    将int转换为char的最快方法是什么

  2. 2

    将数组短转换为char的最快方法

  3. 3

    将 imageURL 从 Firebase 转换为 UIImage 的最快方法是什么?

  4. 4

    将具有10k .txt文件的文件夹转换为数组的最快方法是什么(python)

  5. 5

    在javascript中将json的字段转换为数组的最快方法是什么?

  6. 6

    在PHP中将对象转换为数组的最快方法是什么?

  7. 7

    将char *转换为uint8_t的数组(c)

  8. 8

    将IndexSet转换为int数组的最佳方法是什么?

  9. 9

    SAS:将二进制压缩的数据集转换为使用 char 压缩的数据集的最快方法是什么,反之亦然?

  10. 10

    使用JS或PHP将html转换为pdf的最快方法是什么?

  11. 11

    检查char数组中前导字符的最快方法是什么?

  12. 12

    在JavaScript中将String转换为Number的最快方法是什么?

  13. 13

    将char转换为short

  14. 14

    将 char* 转换为 short*

  15. 15

    将拥有字段的类的列表转换成多个数组的最快方法是什么?--

  16. 16

    在C ++中将十六进制转换为整数的最快方法是什么?

  17. 17

    使用Java 8将字符串数组转换为int数组的最简单方法是什么?

  18. 18

    转换数组字母数字的每个成员的最快方法是什么?

  19. 19

    将 char 数组转换为 uint16_t 数组 C/C++

  20. 20

    在C中将unsigned char数组转换为signed short

  21. 21

    将JavaScript NodeList转换为数组的最快方法?

  22. 22

    将图像转换为字节数组的最快方法

  23. 23

    将数组转换为多行字符串的最快方法

  24. 24

    将数值表值转换为字符数组的最快方法

  25. 25

    将元素追加到数组的最快方法是什么?

  26. 26

    将 CSV 文件从 UTF-16 制表符转换为 UTF-8-SIG 逗号的最快方法

  27. 27

    将C char数组转换为String

  28. 28

    将数组转换为对象数组(包括数组条目作为对象键)的最佳方法是什么?

  29. 29

    对大型字节数组进行排序和解包的最快方法是什么?

热门标签

归档