使用-mfma进行编译时的非法指令

Mat*_*att 2 c++ gcc eigen

我正在使用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永远不会产生非法指令.我跑的程序与gdbbt,但它显示了一个有效(至少对我来说)栈,所以我不认为-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 ()
Run Code Online (Sandbox Code Playgroud)

然后我用debugging(-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));
Run Code Online (Sandbox Code Playgroud)

回溯显示错误从第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;
Run Code Online (Sandbox Code Playgroud)

编译的目的-mfma是看我是否可以提高性能.这是一个错误,Eigen或者更可能是我错误地使用它?

cht*_*htz 6

-mfmaFMA指令集添加到允许的指令集.你需要至少一个Intel-Haswell或AMD-Piledriver CPU.

另外添加-mInstructionSet-march=native永远不会有帮助 - 它已经被包含在内,或者它将允许编译器使用非法指令(在你的CPU上).

  • 如果他的目标是提高他的机器的性能,用`-mtune = native`替换`-march = native`会适得其反. (2认同)

Rus*_*lan 6

要调试非法指令,首先应该查看反汇编,而不是回溯或源代码.但是,在您的情况下,即使从源代码中您也可以很容易地看到违规(非法)指令vfmadd231pd,它来自FMA指令集扩展.但是SandyBridge CPU(其中一个)不支持这种ISA扩展,所以通过在编译器中启用它,你就可以自己动手了.

在Linux上,您可以通过以下shell命令检查您的CPU是否支持FMA:

grep -q '\<fma\>' /proc/cpuinfo && echo supported || echo not supported
Run Code Online (Sandbox Code Playgroud)