SSE - AVX conversion from double to char

别说谁变了你拦得住时间么 提交于 2019-12-04 18:34:19

If you want to convert e.g. 16 doubles to 16 chars per iteration using AVX/SSE then here is some code that works:

#include <iostream>
#include <immintrin.h>

__m128i proc(const __m256d in0, const __m256d in1, const __m256d in2, const __m256d in3)
{
    __m128i v0 = _mm256_cvtpd_epi32(in0);
    __m128i v1 = _mm256_cvtpd_epi32(in1);
    __m128i v2 = _mm256_cvtpd_epi32(in2);
    __m128i v3 = _mm256_cvtpd_epi32(in3);
    __m128i v01 = _mm_packs_epi32(v0, v1);
    __m128i v23 = _mm_packs_epi32(v2, v3);
    return _mm_packs_epi16(v01, v23);
}

int main()
{
    double input[32] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};

    char output[32] = {0};

    for (int i = 0; i < 32; i += 16)                     // two iterations
    {
        __m256d in0 = _mm256_loadu_pd(&input[i]);        // load 4 x 4 doubles
        __m256d in1 = _mm256_loadu_pd(&input[i + 4]);
        __m256d in2 = _mm256_loadu_pd(&input[i + 8]);
        __m256d in3 = _mm256_loadu_pd(&input[i + 12]);

        __m128i out = proc(in0, in1, in2, in3);          // pack to 16 chars

       _mm_storeu_si128(reinterpret_cast<__m128i*>(&output[i]), out);
    }

    for (int i = 0; i < 32; ++i)
    {
        std::cout << (int)output[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

Compile and run:

$ g++ -Wall -mavx double_to_char.cpp && ./a.out 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 

Note that the above code only requires AVX (no need for AVX2).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!