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

Intel AVX-512下int8向量乘法性能优化及epi8支持疑问

8位整数向量乘法的高效实现与指令设计疑问

用户问题与现有实现

我实现了用于int8矩阵乘法的8位整数乘法(uint8_t或int8_t因无扩展操作效果一致),但以下代码运行效率极低,寻求更高效实现方案;同时咨询:为何Intel未提供epi8原生乘法指令?

现有代码:

inline __m512i int8_mul(__m512i a, __m512i b) {
// Convert vectors INT8 to INT16
__m512i a_lo = _mm512_cvtepi8_epi16(_mm512_castsi512_si256(a));
__m512i a_hi = _mm512_cvtepi8_epi16(_mm512_extracti64x4_epi64(a, 1));
__m512i b_lo = _mm512_cvtepi8_epi16(_mm512_castsi512_si256(b));
__m512i b_hi = _mm512_cvtepi8_epi16(_mm512_extracti64x4_epi64(b, 1));

    // Multiply vectors in INT16
    __m512i mul_lo = _mm512_mullo_epi16(a_lo, b_lo);
    __m512i mul_hi = _mm512_mullo_epi16(a_hi, b_hi);
    
    // Combine results
    __m512i result = _mm512_setzero_si512();
    result = _mm512_inserti64x4(result, _mm512_cvtepi16_epi8(mul_lo), 0);
    result = _mm512_inserti64x4(result, _mm512_cvtepi16_epi8(mul_hi), 1);
    return result;

}

高效实现方案

现有代码的主要开销来自重复的数据拆分/转换操作和冗余的结果合并步骤,以下是优化后的实现:

优化后的代码

inline __m512i int8_mul(__m512i a, __m512i b) {
    // 提前拆分512位向量为两个256位的epi8子向量,避免重复指令调用
    __m256i a_lo_256 = _mm512_castsi512_si256(a);
    __m256i a_hi_256 = _mm512_extracti64x4_epi64(a, 1);
    __m256i b_lo_256 = _mm512_castsi512_si256(b);
    __m256i b_hi_256 = _mm512_extracti64x4_epi64(b, 1);

    // 将epi8扩展为epi16(int8用符号扩展,uint8可替换为_mm512_cvtepu8_epi16零扩展)
    __m512i a_lo = _mm512_cvtepi8_epi16(a_lo_256);
    __m512i a_hi = _mm512_cvtepi8_epi16(a_hi_256);
    __m512i b_lo = _mm512_cvtepi8_epi16(b_lo_256);
    __m512i b_hi = _mm512_cvtepi8_epi16(b_hi_256);

    // 对应元素相乘(保留低16位结果)
    __m512i mul_lo = _mm512_mullo_epi16(a_lo, b_lo);
    __m512i mul_hi = _mm512_mullo_epi16(a_hi, b_hi);

    // 转换回epi8并直接合并结果,减少零初始化步骤
    __m256i res_lo = _mm512_cvtepi16_epi8(mul_lo);
    __m256i res_hi = _mm512_cvtepi16_epi8(mul_hi);
    return _mm512_inserti64x4(_mm512_castsi256_si512(res_lo), res_hi, 1);
}

额外优化建议(针对矩阵乘法场景)

如果你的最终场景是int8矩阵乘法,优先使用Intel专门提供的点积指令,而非单独实现乘法:

  • 对于有符号int8,使用_mm512_dpwssd_epi32:一次指令完成8对int8元素的乘积累加,输出int32结果
  • 对于无符号uint8,使用_mm512_dpbusd_epi32:功能类似,针对无符号数优化

这些指令将乘法和累加合并在硬件层面完成,比单独做乘法再累加的效率提升数倍,完全覆盖矩阵乘法的核心需求。


为何Intel未提供epi8原生乘法指令

主要基于硬件成本、实际需求和指令集优先级的权衡:

  • 硬件成本与收益不对等:512位epi8向量包含64个元素,若实现原生乘法,需要64个独立的8x8乘法器,会大幅增加CPU核心的面积和功耗。而实际场景中,epi8的核心用途是矩阵乘法,这类场景更需要乘积累加(点积)而非单独乘法,Intel的点积指令可以共享加法器,硬件效率更高。
  • 现有指令可替代:通过epi16乘法配合类型转换,已经可以实现epi8乘法的效果,虽然有额外开销,但对于非热点场景完全够用。
  • 指令集设计优先级:AVX-512的扩展优先针对AI、HPC等高性能场景,比如bfloat16支持、向量掩码操作、点积加速等,这些场景的收益远大于单独的epi8乘法指令。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 19:41:06