使用 -mfma 编译时出现非法指令
Illegal Instruction when compiling with -mfma
我正在 Intel SandyBridge E5-2670 上使用 GCC 5.3.0 进行编译。当我使用这些标志 -O3 -DEIGEN_NO_DEBUG -std=c++11 -Wall -Wextra -Werror -march=native -ffast-math
时,代码运行没有错误。当我添加 -mfma
时,我得到了非法指令。
我认为使用 -march=native
永远不会产生非法指令。我 运行 使用 gdb
和 bt
的程序,但它显示了一个有效的(至少对我而言)堆栈,所以我认为 -mfma
没有暴露错误的指针或其他内存问题。
#0 0x000000000043a59c in ConvexHull::SortConvexHull() ()
#1 0x000000000043badd in ConvexHull::ConvexHull(Eigen::Matrix<double, -1, -1, 0, -1, -1>) ()
#2 0x000000000040b794 in Group::BuildCatElement() ()
#3 0x0000000000416b60 in SurfaceModel::ProcessGroups() ()
#4 0x00000000004435c6 in MainLoop(Inputs&, std::ostream&) ()
#5 0x000000000040494e in main ()
然后我通过调试重新编译 (-O0 -g
),所有其他选项相同,gdb
返回
0x00000000004140df in Eigen::internal::pmadd<double __vector(4)>(double __vector(4) const&, double __vector(4) const&, double __vector(4) const&) (a=..., b=..., c=...)
at ./../eigen-eigen-5a0156e40feb/Eigen/src/Core/arch/AVX/PacketMath.h:178
178 __asm__("vfmadd231pd %[a], %[b], %[c]" : [c] "+x" (res) : [a] "x" (a), [b] "x" (b));
回溯显示错误从第 259 行开始
using namespace Eigen;
252 gridPnts.rowwise() -= gridPnts.colwise().mean(); //gridPnts is MatrixXd (X by 3)
253 Matrix3d S = gridPnts.transpose() * gridPnts;
254 S /= static_cast<double>(gridPnts.rows() - 1);
255 Eigen::SelfAdjointEigenSolver<MatrixXd> es(S);
256 Eigen::Matrix<double, 3, 2> trans;
257 trans = es.eigenvectors().block<3, 2>(0, 1);
258 MatrixXd output(gridPnts.rows(), 2);
259 output = gridPnts * trans;
用 -mfma
编译的目的是看看我是否可以提高性能。这是 Eigen
中的错误还是我使用不当?
-mfma
将 FMA instruction set 添加到允许的指令集中。为此,您至少需要一个 Intel-Haswell 或 AMD-Piledriver CPU。
将 -m
InstructionSet 添加到 -march=native
将无济于事——它要么已经被包含,要么将允许编译器使用非法指令 (在你的 CPU).
要调试非法指令,您应该首先查看反汇编,而不是回溯或源代码。但是,在您的情况下,即使从源代码中您也可以很容易地看到有问题的(非法)指令是 vfmadd231pd
,它来自 FMA 指令集扩展。但是 SandyBridge CPUs(您拥有的其中之一)不支持此 ISA 扩展,因此在编译器中启用它是搬起石头砸自己的脚。
在 Linux 上,您可以通过此 shell 命令检查您的 CPU 是否支持 FMA:
grep -q '\<fma\>' /proc/cpuinfo && echo supported || echo not supported
我正在 Intel SandyBridge E5-2670 上使用 GCC 5.3.0 进行编译。当我使用这些标志 -O3 -DEIGEN_NO_DEBUG -std=c++11 -Wall -Wextra -Werror -march=native -ffast-math
时,代码运行没有错误。当我添加 -mfma
时,我得到了非法指令。
我认为使用 -march=native
永远不会产生非法指令。我 运行 使用 gdb
和 bt
的程序,但它显示了一个有效的(至少对我而言)堆栈,所以我认为 -mfma
没有暴露错误的指针或其他内存问题。
#0 0x000000000043a59c in ConvexHull::SortConvexHull() ()
#1 0x000000000043badd in ConvexHull::ConvexHull(Eigen::Matrix<double, -1, -1, 0, -1, -1>) ()
#2 0x000000000040b794 in Group::BuildCatElement() ()
#3 0x0000000000416b60 in SurfaceModel::ProcessGroups() ()
#4 0x00000000004435c6 in MainLoop(Inputs&, std::ostream&) ()
#5 0x000000000040494e in main ()
然后我通过调试重新编译 (-O0 -g
),所有其他选项相同,gdb
返回
0x00000000004140df in Eigen::internal::pmadd<double __vector(4)>(double __vector(4) const&, double __vector(4) const&, double __vector(4) const&) (a=..., b=..., c=...)
at ./../eigen-eigen-5a0156e40feb/Eigen/src/Core/arch/AVX/PacketMath.h:178
178 __asm__("vfmadd231pd %[a], %[b], %[c]" : [c] "+x" (res) : [a] "x" (a), [b] "x" (b));
回溯显示错误从第 259 行开始
using namespace Eigen;
252 gridPnts.rowwise() -= gridPnts.colwise().mean(); //gridPnts is MatrixXd (X by 3)
253 Matrix3d S = gridPnts.transpose() * gridPnts;
254 S /= static_cast<double>(gridPnts.rows() - 1);
255 Eigen::SelfAdjointEigenSolver<MatrixXd> es(S);
256 Eigen::Matrix<double, 3, 2> trans;
257 trans = es.eigenvectors().block<3, 2>(0, 1);
258 MatrixXd output(gridPnts.rows(), 2);
259 output = gridPnts * trans;
用 -mfma
编译的目的是看看我是否可以提高性能。这是 Eigen
中的错误还是我使用不当?
-mfma
将 FMA instruction set 添加到允许的指令集中。为此,您至少需要一个 Intel-Haswell 或 AMD-Piledriver CPU。
将 -m
InstructionSet 添加到 -march=native
将无济于事——它要么已经被包含,要么将允许编译器使用非法指令 (在你的 CPU).
要调试非法指令,您应该首先查看反汇编,而不是回溯或源代码。但是,在您的情况下,即使从源代码中您也可以很容易地看到有问题的(非法)指令是 vfmadd231pd
,它来自 FMA 指令集扩展。但是 SandyBridge CPUs(您拥有的其中之一)不支持此 ISA 扩展,因此在编译器中启用它是搬起石头砸自己的脚。
在 Linux 上,您可以通过此 shell 命令检查您的 CPU 是否支持 FMA:
grep -q '\<fma\>' /proc/cpuinfo && echo supported || echo not supported