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

基于AVX2/AVX512的int16_t型256x256二维LUT快速查表优化

基础存储与循环优化
  • 首先调整B矩阵的存储格式:将原来N行K列的B矩阵转置为K行N列,转置后B_t[k*N + j] = 原B[j*K + k]。原代码最内层k循环访问B的步长为K,缓存命中率极低,转置后访问步长为1,连续读取可以充分利用CPU缓存,这个优化的收益通常远高于单独指令集优化。
  • 循环分块:根据CPU L2/L3缓存大小,将M、N、K拆分为32/64/128大小的子块,保证运算过程中用到的A、B子块和LUT都能留在缓存中,避免频繁缓存失效。
  • LUT对齐声明:将256x256的LUT展开为一维数组并按64字节缓存行对齐,声明为const int16_t lut_flat[65536] __attribute__((aligned(64))),每个元素的索引直接通过(a << 8) | b计算,把二维查表转为一维索引查表,方便后续SIMD操作。注意LUT总大小为128KB,完全可以放入CPU L2缓存,不需要额外分块。
AVX512 指令集优化实现

最内层k循环可以一次性处理32组a、b值,对应512位寄存器的32个int8_t容量,核心流程如下:

#include <immintrin.h>

// 假设K是32的倍数,非倍数的剩余部分用标量补充即可
for(int i = 0; i < M; ++i) {
    for(int j = 0; j < N; ++j) {
        __m512i sum = _mm512_setzero_si512();
        for(int k = 0; k < K; k += 32) {
            // 加载32个a和32个b
            __m512i a_vec = _mm512_loadu_si512((const __m512i*)(A + i*K + k));
            __m512i b_vec = _mm512_loadu_si512((const __m512i*)(B_t + k*N + j));
            // a左移8位,拼接b得到16位索引
            __m512i a_shift = _mm512_slli_epi16(a_vec, 8);
            __m512i idx = _mm512_or_si512(a_shift, b_vec);
            // 索引零扩展为32位,计算字节偏移(每个int16占2字节)
            __m512i idx_32 = _mm512_cvtepu16_epi32(_mm512_extracti32x8_epi32(idx, 0));
            __m512i gather_offset = _mm512_slli_epi32(idx_32, 1);
            // gather 16个int16值,累加
            __m512i lut_vals1 = _mm512_i32gather_epi16(lut_flat, gather_offset, 2);
            sum = _mm512_add_epi16(sum, lut_vals1);
            // 处理剩下的16个索引
            idx_32 = _mm512_cvtepu16_epi32(_mm512_extracti32x8_epi32(idx, 1));
            gather_offset = _mm512_slli_epi32(idx_32, 1);
            __m512i lut_vals2 = _mm512_i32gather_epi16(lut_flat, gather_offset, 2);
            sum = _mm512_add_epi16(sum, lut_vals2);
        }
        // 累加所有sum中的元素得到最终temp
        C[i*N + j] = _mm512_reduce_add_epi32(_mm512_cvtepi16_epi32(sum));
    }
}

如果K不是32的倍数,只需要在循环结束后处理剩余不足32的k值,用标量逻辑计算即可。

编译与进阶优化
  • g++编译时添加参数:-O3 -mavx512f -mavx512bw -march=native -falign-loops=64,开启最高等级优化,启用AVX512相关指令支持,自动适配当前CPU特性。
  • 多线程并行:如果M、N规模较大,可以在最外层i循环添加#pragma omp parallel for,结合OpenMP实现多核心并行,线性提升运算速度。
  • 循环展开:可以将内层k循环的步长调整为64,每次处理两次AVX512操作后再累加,进一步掩盖指令延迟,提升流水线利用率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 11:06:03