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

如何验证Eigen3是否生成AVX2或AVX512F指令代码?

Eigen3 + AVX/AVX2/AVX-512F 向量化验证与优化实践

问题背景

我正在开发一款涉及大量低延迟硬实时矩阵运算的程序,采用Eigen3库实现。目标是在生产环境中通过AVX-512F SIMD向量化技术提升性能。当前在Ubuntu系统上实验,通过vcpkg安装Eigen3,本机支持AVX2,后续将通过BIOS开启AVX-512F。

初始验证情况

我用以下命令分析目标文件的寄存器使用:

objdump -d main.o | grep zmm
objdump -d main.o | grep ymm
objdump -d main.o | grep xmm

结果zmm和ymm相关指令无输出,仅xmm能查到寄存器操作,示例片段如下:

3d84:   0f 28 08                movaps (%rax),%xmm1
3d87:   0f 29 4d d0             movaps %xmm1,-0x30(%rbp)
3d8b:   0f 29 45 e0             movaps %xmm0,-0x20(%rbp)
3d8f:   0f 28 45 d0             movaps -0x30(%rbp),%xmm0
3d93:   0f 12 45 e8             movlps -0x18(%rbp),%xmm0
3d9f:   0f 28 08                movaps (%rax),%xmm1
3da2:   0f 29 4d b0             movaps %xmm1,-0x50(%rbp)
3da6:   0f 29 45 c0             movaps %xmm0,-0x40(%rbp)
3daa:   0f 28 45 b0             movaps -0x50(%rbp),%xmm0
3dae:   0f 58 45 c0             addps  -0x40(%rbp),%xmm0
3db2:   0f 29 45 80             movaps %xmm0,-0x80(%rbp)
3db6:   0f 28 45 80             movaps -0x80(%rbp),%xmm0
3dba:   0f 28 4d 80             movaps -0x80(%rbp),%xmm1
3dbe:   0f c6 c1 01             shufps $0x1,%xmm1,%xmm0

我需要确认:

  1. 当前g++是否为Eigen3生成了AVX1(128位)代码?
  2. 如何验证是否生成了正确的AVX2或AVX-512F SIMD代码?

更新内容:测试代码与编译命令

测试代码

#include <eigen3/Eigen/Core>
#include <eigen3/Eigen/Dense>
using namespace Eigen;
int main()
{
//  Matrix4f a, b, cadd, cmul, ci, ct, d;
//  a = Matrix4f::Random();
//  b = Matrix4f::Random();
    MatrixXf a(100, 100),b(100, 100),cadd(100, 100), cmul(100, 100), ci(100, 100), ct(100, 100);
    a = MatrixXf::Random(100, 100);
    b = MatrixXf::Random(100, 100);
    cadd = a + b;
    cmul = a * b;
    ci = cadd.inverse();
    ct = cadd.transpose();
}

初始编译命令

g++ -Wall -fexceptions -I/home/user/vcpkg/installed/x64-linux/include -c /home/user/Desktop/VectorClass/main.cpp -o obj/Debug/main.o
g++ -L/home/user/vcpkg/installed/x64-linux/debug/lib -o bin/Debug/VectorClass obj/Debug/main.o  -mavx2 -mtune=native -host=native -march=native

最终验证结果与优化编译命令

反汇编输出

  • objdump -d main.o | grep ymm结果:
14f:    c5 fe 7f 45 98           vmovdqu %ymm0,-0x68(%rbp)
231:    c5 fd 7f 85 50 fe ff     vmovdqa %ymm0,-0x1b0(%rbp)
  • objdump -d main.o | grep zmm结果:
a1:    62 f1 7c 48 28 74 24     vmovaps 0x80(%rsp),%zmm6
 ac:    62 f1 4c 48 58 44 24     vaddps 0x40(%rsp),%zmm6,%zmm0
 b4:    62 f1 7c 48 29 44 24     vmovaps %zmm0,0xc0(%rsp)
228:    62 f1 7c 48 28 7c 24     vmovaps 0x180(%rsp),%zmm7
230:    62 f1 7c 48 29 7c 24     vmovaps %zmm7,0x100(%rsp)
2d0:    62 f1 7d 48 6f 05 00     vmovdqa32 0x0(%rip),%zmm0        # 2da <main+0x2da>
2dd:    62 f2 7d 48 16 44 24     vpermps 0xc0(%rsp),%zmm0,%zmm0
2e5:    62 f1 7c 48 29 44 24     vmovaps %zmm0,0x180(%rsp)

对应的优化编译命令

g++ -Wall -fexceptions -I/home/user/vcpkg/installed/x64-linux/include -c main.cpp -o main.out -mavx512f -mfma -mtune=native -host=native  -march=native -mprefer-vector-width=512 -O3 -fno-math-errno -ffinite-math-only -fno-rounding-math  -funsafe-math-optimizations

问题解答

初始xmm指令的归属

你看到的movaps、addps等是SSE指令,不属于AVX1。AVX1的指令会带V前缀(如vmovaps),且使用ymm寄存器。当时没生成AVX/AVX2代码的核心原因:

  • 编译阶段(-c步骤)未开启优化等级(默认-O0),Eigen的向量化优化需要至少-O2才能激活;
  • 初始编译命令中-mavx2等SIMD参数仅加在链接阶段,编译目标文件时未生效,导致编译器未启用AVX2指令集。

验证AVX2/AVX-512F代码生成的方法

  1. 识别指令特征
    • AVX2指令:以V开头,使用ymm寄存器(例如vmovdqu、vmovdqa),机器码前缀为C5/C4;
    • AVX-512F指令:机器码以62开头,使用zmm寄存器(例如vmovaps、vaddps搭配zmm);
  2. 正确配置编译参数
    • 必须在编译阶段(-c步骤)添加指令集参数:-mavx2(AVX2)或-mavx512f(AVX-512F);
    • 开启优化等级-O3,配合-mprefer-vector-width=512强制优先使用512位向量;
    • 添加-funsafe-math-optimizations、-ffinite-math-only等参数,让Eigen能最大化利用SIMD进行矩阵运算优化;
  3. 反汇编验证
    • 用objdump -d main.o | grep ymm检查AVX2指令;
    • 用objdump -d main.o | grep zmm检查AVX-512F指令;
    • 也可以用objdump -d main.o | grep -E 'vmov|vadd|vperm'过滤AVX系列指令。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:05:14