I have grayscale image from uint8_t values. I want to load data to SIMD. I load 16 values and convert them to two __m256 float registers.
I use:
uint8_t * data = .....
size_t index = ....
//load 16 uint8_t (16 * 8 = 128bit)
__m128i val = _mm_loadu_si128((const __m128i*)(data + index));
//convert to 16bit int
__m128i lo16 = _mm_unpacklo_epi8(val, _mm_setzero_si128());
__m128i hi16 = _mm_unpackhi_epi8(val, _mm_setzero_si128());
//convert to 32bit int
__m256i lo32 = _mm256_cvtepi16_epi32(lo16);
__m256i hi32 = _mm256_cvtepi16_epi32(hi16);
//convert to float
__m256 lo = _mm256_cvtepi32_ps(lo32);
__m256 hi = _mm256_cvtepi32_ps(hi32);
Is there a better way how to do this (without AVX-512), than my solution?
Would it be better to load _mm256_loadu_si256 and "split" it to 4 __m256 registers?