You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Eigen框架启用AVX512编译时整数矩阵乘法性能异常下降的原因排查问询

Eigen框架启用AVX512编译时整数矩阵乘法性能异常下降的原因排查问询

我最近在测试无符号32位整数矩阵乘法的性能,结果发现了一个非常反常的现象:当用AVX512指令集编译Eigen的无符号32位整数矩阵乘法时,性能会出现大幅下降,而浮点数矩阵乘法的性能在AVX2和AVX512编译下基本一致。下面是我的完整测试过程和发现,想请教社区的大佬们这可能是什么原因导致的?

问题发现与多环境验证

初始异常

一开始我以为整数矩阵乘法比浮点数慢是正常情况,但没想到Eigen优化后的u32矩阵乘法,居然比自己写的5行naive实现还慢3-5倍。进一步调整编译选项后,我发现了更关键的差异:

  • -march=skylake(仅启用AVX2、FMA)编译时,Eigen的u32矩阵乘性能符合预期;
  • 用AVX512相关参数编译时,Eigen的u32矩阵乘性能暴跌,而浮点数矩阵乘的速度在两种编译选项下几乎没有差异。

多环境测试排除干扰

我先后在多个环境中验证,排除了硬件和虚拟机的影响:

  1. VM中的i5-11400F:AVX2编译的Eigen u32乘比AVX512快很多,浮点乘无差异,最初以为是VM配置问题,但换物理机后问题仍存在;
  2. 物理机i5-11400F:AVX2编译的Eigen u32乘性能回归正常,但AVX512编译下的u32乘依然远慢于AVX2;
  3. AMD Ryzen 9 9950X(支持AVX512):同样出现AVX512编译下Eigen u32矩阵乘性能大幅下降的问题,浮点乘性能无明显差异。

测试环境明细

  • CPU型号:Intel i5-11400F(VM/物理机)、AMD Ryzen 9 9950X
  • 操作系统:Ubuntu 20.04
  • 编译器:g++ 13.3
  • Eigen版本:5.0.0(代码中显示为3.5.0)
  • OpenBLAS版本:0.3.8(编译配置:NO_LAPACKE、DYNAMIC_ARCH、NO_AFFINITY、USE_OPENMP;运行核心:Prescott)

依赖安装命令

sudo apt update && sudo apt install -y software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install -y gcc-13 g++-13
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 130
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 130
sudo update-alternatives --install /usr/bin/cpp cpp /usr/bin/cpp-13 130

# 安装Eigen 5.0.0
sudo apt install -y build-essential cmake git
git clone --depth=1 --branch 5.0.0 https://gitlab.com/libeigen/eigen.git
cmake -S eigen -B build -DCMAKE_BUILD_TYPE=Release -DEIGEN_BUILD_TESTING=OFF
sudo cmake --install build
sudo apt install -y libopenblas-openmp-dev

编译与运行命令

编译命令

AVX2版本(-march=skylake)

g++ -std=c++17 -O3 bench_eigen.cpp -march=skylake -mavx2 -mfma -I/usr/local/include/eigen3 -DEIGEN_USE_BLAS -DNDEBUG -DEIGEN_DONT_PARALLELIZE -o bench_eigen -lopenblas -ldl -lpthread

AVX512版本

g++ -std=c++17 -O3 bench_eigen.cpp -march=native -mavx512f -mavx512vl -mavx512bw -mavx512dq -mavx2 -mfma -I/usr/local/include/eigen3 -DEIGEN_USE_BLAS -DNDEBUG -DEIGEN_DONT_PARALLELIZE -o bench_eigen -lopenblas -ldl -lpthread

运行命令(强制单线程)

为排除多线程干扰,我用以下命令强制单线程运行:

OMP_NUM_THREADS=1 \
OPENBLAS_NUM_THREADS=1 \
MKL_NUM_THREADS=1 \
BLIS_NUM_THREADS=1 \
VECLIB_MAXIMUM_THREADS=1 \
NUMEXPR_MAX_THREADS=1 \
TBB_NUM_THREADS=1 \
taskset -c 0 ./bench_eigen

具体测试结果

所有结果耗时单位为毫秒,测试矩阵为M×M

  • A (naive u32):手动实现的naive无符号32位整数矩阵乘法
  • E (Eigen u32):Eigen优化的无符号32位整数矩阵乘法
  • F (Eigen float):Eigen的32位浮点数矩阵乘法

1. AVX2编译结果

测试环境矩阵大小MA (naive u32)E (Eigen u32)F (Eigen float)
i5-11400F(VM)1280.1957860.2306650.343123
i5-11400F(VM)2562.535912.436432.55185
i5-11400F(VM)51221.024612.979310.7131
i5-11400F(VM)102499.940260.182892.6357
i5-11400F(VM)20481752.68602.128790.347
i5-11400F(VM)409615556.74897.886155.12
i5-11400F(VM)819212599134135.346756.6
i5-11400F(物理机)1280.121630.1164010.075121
i5-11400F(物理机)2561.095520.9193450.371853
i5-11400F(物理机)51210.68126.04382.51853
i5-11400F(物理机)102479.696246.313718.0736
i5-11400F(物理机)20481042.06369.876135.139
i5-11400F(物理机)409610479.92960.941050(原数据不全)
i5-11400F(物理机)819290380.723885.28307.87

2. AVX512编译结果

测试环境矩阵大小MA (naive u32)E (Eigen u32)F (Eigen float)
i5-11400F(VM)819210659016930745510.9
i5-11400F(物理机)819290707.91314408217.99
AMD Ryzen 9 9950X819249783.9785673616.15

关键结论

从所有测试结果中能明确看到:

  1. 无论Intel还是AMD CPU,AVX512编译的Eigen u32矩阵乘法耗时都远高于AVX2版本(比如物理机i5的8192大小矩阵,AVX512下Eigen u32耗时131440ms,AVX2下仅23885.2ms);
  2. 浮点数矩阵乘法在AVX2和AVX512编译下的性能基本持平,无明显差异;
  3. Naive实现的u32矩阵乘法在AVX2和AVX512编译下的性能差异不大。

想请教大家,这种Eigen整数矩阵乘法在AVX512编译下性能暴跌的情况,可能是编译器的优化逻辑问题?还是Eigen对AVX512整数矩阵乘法的支持存在bug?或者是OpenBLAS的适配问题?

火山引擎 最新活动