我正在编写一个软件栅格,大量使用英特尔的本质(不包括AVX512)。颜色由32位无符号表示,实际上只有4块8位颜色(RGBA)。因此,一个8种颜色的向量可以保存在一个单一的__mm256颜色变量中。但是,我需要通过将单个颜色乘以浮点数来操作这个数组中的单个颜色。换句话说,我可能有另一个浮点/ps值的向量,__mm256 rLight,其中我想要将颜色向量中相应的8位无符号R乘以rLight变量中的浮点数。我找不到任何理智的方法来做这件事。我需要做的似乎是将感兴趣的8个字节提取到一个__mm256浮点数数组中,然后进行乘法,然后将它们转换回无符号,并将它们重新粘贴到原始数组中,但我正在挣扎。
任何看起来很有希望的指示都将不胜感激。
发布于 2020-07-05 22:13:05
--一个8种颜色的向量可以保存在一个__mm256颜色变量中。
这不是最好的方法。将很难添加10+位颜色深度,或伽马校正,或颜色分级。要获得最佳性能,可以考虑使用16位整数,或者浮动。
,我找不到任何理智的方法来做这件事。
和_mm256_fmadd_ps中所有8个浮点数的2条指令。
__m256i scaleBytes( __m256i rgba,__m256i mul ){ __m256i low = _mm256_and_si256( rgba,_mm256_set1_epi16( 0xFF ) );__m256i high = _mm256_and_si256( rgba,_mm256_set1_epi16( 0xF00) );low = _mm256_mulhi_epu16(低,mul );high = _mm256_mulhi_epu16(高,mul );low = _mm256_and_si256( high,_mm256_set1_epi16( 0xFF00 ) );返回_mm256_or_si256(低,高);}
更新:我刚刚意识到,对于步骤1,您不需要缩放,只需要偏移就足够了。
// Test values
__m256 floats = _mm256_setr_ps( -1, 0, 0.11f, 0.33f, 0.99f, 1, 1.11f, 12 );
// Floats have 23 bits of mantissa.
// We want [0..1] to map to the least significant 15 of them.
// Therefore, we need to offset the floats by 2 ^ ( 23 - 15 ) = 2 ^ 8
constexpr float offsetFloat = 0x1p8f;
// Same value bit-casted to integer, too bad std::bit_cast only appeared in C++/20
// https://www.h-schmidt.net/FloatConverter/IEEE754.html
constexpr int offsetInt = 0x43800000;
// Compute the integers
floats = _mm256_add_ps( floats, _mm256_set1_ps( offsetFloat ) );
const __m256i result = _mm256_sub_epi32( _mm256_castps_si256( floats ), _mm256_set1_epi32( offsetInt ) );
// Print the result
alignas( 32 ) std::array<int, 8> scalars;
_mm256_store_si256( ( __m256i * )scalars.data(), result );
for( int i : scalars )
printf( "0x%04x ", i );
printf( "\n" );https://stackoverflow.com/questions/62678875
复制相似问题