You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效将含32个uint8_t的__m256i转为4个__m256浮点向量

AVX2高效实现__m256i(uint8)到4个__m256(float)的转换

核心优化实现

针对32个无符号8位整数的__m256i向量,我们可以通过AVX2的128位提取+64位块重排指令,高效拆分出4组8个uint8数据,再完成无符号扩展与浮点转换,比你设想的方案更紧凑:

#include <immintrin.h>

void unpack_uint8_to_float(__m256i input_32u8, __m256* out_floats[4]) {
    // 拆分__m256i为两个128位向量
    __m128i low_128 = _mm256_castsi256_si128(input_32u8);
    __m128i high_128 = _mm256_extracti128_si256(input_32u8, 1);

    // 重排128位向量的高低64位,得到4个含8个uint8的目标块(低64位有效)
    __m128i block0 = low_128;                // 原向量第0-7个uint8
    __m128i block1 = _mm_shuffle_epi32(low_128, 0x4E); // 原向量第8-15个uint8(交换low_128的高低64位)
    __m128i block2 = high_128;               // 原向量第16-23个uint8
    __m128i block3 = _mm_shuffle_epi32(high_128, 0x4E); // 原向量第24-31个uint8

    // 无符号扩展uint8到int32,再转换为float
    out_floats[0] = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(block0));
    out_floats[1] = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(block1));
    out_floats[2] = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(block2));
    out_floats[3] = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(block3));
}

结合像素平方差业务的额外优化

你提到的场景是计算RGB通道平方差求和,完全可以跳过浮点转换,用整数运算实现,效率更高:

  1. 符号扩展差值到int16:_mm256_sub_epi8的结果是有符号int8,直接用_mm256_cvtepi8_epi16完成符号扩展:
__m128i low_diff = _mm256_castsi256_si128(diff_32i8);
__m128i high_diff = _mm256_extracti128_si256(diff_32i8, 1);
__m256i low_16 = _mm256_cvtepi8_epi16(low_diff);
__m256i high_16 = _mm256_cvtepi8_epi16(high_diff);
  1. 计算平方:用_mm256_mullo_epi16完成int16乘法,得到int32的平方值:
__m256i low_sq = _mm256_mullo_epi16(low_16, low_16);
__m256i high_sq = _mm256_mullo_epi16(high_16, high_16);
  1. 通道平方求和:通过排列指令对齐同像素的RGB通道平方值,再累加:
// 排列掩码:将G、B通道的平方值映射到对应R通道的位置
const __m256i perm_g = _mm256_setr_epi32(1,4,7,10,13,16,19,22);
const __m256i perm_b = _mm256_setr_epi32(2,5,8,11,14,17,20,23);

__m256i low_g_sq = _mm256_permutevar8x32_epi32(low_sq, perm_g);
__m256i low_b_sq = _mm256_permutevar8x32_epi32(low_sq, perm_b);
__m256i low_pixel_sum = _mm256_add_epi32(_mm256_add_epi32(low_sq, low_g_sq), low_b_sq);

// 对high_sq执行相同操作得到high_pixel_sum

内容的提问来源于stack exchange,提问作者Mandelmus100

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 21:45:02