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

AVX优化矩阵乘法索引访问变慢及Clang编译性能异常咨询

AVX指令集矩阵乘法优化实践与性能问题

我基于AVX指令集做矩阵乘法优化实践,写了简易的矩阵乘法基准测试代码,逐步叠加优化策略,探索能达到的性能上限,首先给出朴素实现版本,以及我写的最简AVX实现版本。

基础实现代码

朴素版矩阵乘法

void mmult_naive()
{
    int i, j, k = 0;
    // 遍历矩阵A的每一行元素
    for (i = 0; i < SIZE; i++) {
        // 遍历矩阵B的每一列元素
        for (j = 0; j < SIZE; j++) {

            for (k = 0; k < SIZE; k++) {
                matrix_C[i][j] += matrix_A[i][k] * matrix_B[k][j];
            }
        }
    }
}

带B矩阵转置的AVX实现

我选择先对矩阵B做转置,方便把内存里连续存放的数据直接加载到向量寄存器,这个方案运行正常,达到了预期的加速效果,代码如下:

void mmult_avx_transposed()
{
    __m256 row_vector_A;
    __m256 row_vector_B;
    int i, j, k = 0;

    __m256 int_prod;

    // 转置矩阵B
    transposeMatrix();

    for (i = 0; i < SIZE; i++) {
        for (j = 0; j < SIZE; j++) {
            int_prod = _mm256_setzero_ps();
            for (k = 0; k < (SIZE / 8); k++) {
                row_vector_A = _mm256_load_ps(&matrix_A[i][k * 8]);
                row_vector_B = _mm256_load_ps(&T_matrix[j][k * 8]);
                int_prod = _mm256_fmadd_ps(row_vector_A, row_vector_B, int_prod);
            }
            matrix_C[i][j] = hsum_single_avx(int_prod);
        }
    }
}

无转置逐索引构造向量的AVX实现

测试边长N>1024的N×N矩阵执行耗时时,我觉得如果能找到更合理的元素访问方式,或许可以省掉转置步骤——转置函数本身大概占总执行时间的4%~5%,属于很容易优化的性能点。
于是我删掉了transposeMatrix()转置步骤,把原代码里第二个_mm256_load_ps调用替换成了逐元素索引构造向量的代码:

row_vector_B = _mm256_setr_ps(matrix_B[k * 8][j], matrix_B[(k * 8) + 1][j], matrix_B[(k * 8) + 2][j], matrix_B[(k * 8) + 3][j],
                    matrix_B[(k * 8) + 4][j], matrix_B[(k * 8) + 5][j], matrix_B[(k * 8) + 6][j], matrix_B[(k * 8) + 7][j]);

但替换之后代码运行性能反而暴跌。

性能测试结果

本次测试所有代码均在i7-8700处理器、Arch Linux系统下编译,编译参数为-O3、-mavx2、-march=native,使用的g++版本为12.1.0,clang版本为14.0.6。

GCC编译版本耗时

MMULT_NAIVE execution time: 195,499 us
MMULT_AVX_TRANSPOSED execution time: 127,802 us
MMULT_AVX_INDEXED execution time: 1,482,524 us

Clang编译版本耗时

我尝试用Clang编译器编译验证性能表现,结果性能反而更差:

MMULT_NAIVE execution time: 2,027,125 us
MMULT_AVX_TRANSPOSED execution time: 125,781 us
MMULT_AVX_INDEXED execution time: 1,798,410 us

待解答的两个技术疑问

  • 为什么用逐索引构造向量的无转置AVX实现,运行速度远慢于转置版本,甚至比朴素实现还慢?
  • 相同编译参数下,Clang编译出来的版本为什么性能异常,连朴素实现的运行速度都远低于GCC编译的对应版本?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:27:30