Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用-mfma编译时指令非法_C++_Gcc_Eigen - Fatal编程技术网

C++ 使用-mfma编译时指令非法

C++ 使用-mfma编译时指令非法,c++,gcc,eigen,C++,Gcc,Eigen,我在英特尔SandyBridge E5-2670上使用GCC 5.3.0进行编译。当我使用这些标志时,-O3-DEIGEN\u NO\u DEBUG-std=c++11-Wall-Wextra-Werror-march=native-ffast math代码运行时不会出错。当我添加-mfma时,我得到非法指令 我认为使用-march=native永远不会产生非法指令。我用gdb和bt运行了这个程序,但它显示了一个有效的堆栈(至少对我来说是这样),所以我认为-mfma不会暴露坏指针或其他内存问题

我在英特尔SandyBridge E5-2670上使用GCC 5.3.0进行编译。当我使用这些标志时,
-O3-DEIGEN\u NO\u 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 ()
回溯显示错误从第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;
使用名称空间特征;
252 gridPnts.rowwise()-=gridPnts.colwise().mean()//gridPnts是矩阵xXD(X X X 3)
253 Matrix3d S=gridPnts.transpose()*gridPnts;
254 S/=static_cast(gridPnts.rows()-1);
255个特征::自伴特征解算器;
256本征::矩阵变换;
257 trans=es.特征向量()块(0,1);
258矩阵XXD输出(gridPnts.rows(),2);
259输出=gridPnts*trans;

使用
-mfma
编译的目的是看我是否可以提高性能。这是否是
Eigen
中的错误,或者更可能是我没有正确使用它?

-mfma
将添加到允许的指令集中。你需要至少一个英特尔Haswell或AMD Piledriver的CPU


-m
InstructionSet添加到
-march=native
中永远不会有任何帮助——要么它已经包含,要么它将允许编译器使用非法指令(在您的CPU上)。

要调试非法指令,您首先应该查看反汇编,而不是回溯或源代码。但在您的情况下,即使从源代码中,您也可以很容易地看到违规(非法)指令是,它来自FMA指令集扩展。但是您拥有的SandyBridge CPU不支持此ISA扩展,因此在编译器中启用它,您就彻底失败了

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

grep-q'\'/proc/cpuinfo&&echo受支持| | echo不受支持

可能与此相关。在无关的情况下;小心使用
-ffast math
-确保你知道它会带来什么把戏,以及在哪里会因此得到错误的结果-如果你知道自己在做什么,这很有用,但是请注意,它正在违反标准,并且存在一些棘手的陷阱-我个人的经验是,有限的性能增益不值得花时间追踪奇怪的bug。@JesperJuhl感谢您对
-ffast math
的评论。这里的练习是查看仅使用编译器选项就可以发现哪些性能增益/损耗。如果我们决定使用它,我们当然需要按照您的建议进行彻底审查。欢迎您。为了使用编译器选项获得安全的性能,我建议您对
-O2
vs
-O3
vs
-Os
进行基准测试,您最肯定的是要研究LTO和PGO-在我的例子中,后两种方法会显著减少可执行文件/库的大小以及可测量的加速,而且所有这些都不需要使用违反标准所提供的保证的技巧(尽管使用LTO可以获得更长的构建时间)。如果他的目标是提高机器的性能,那么将
-march=native
替换为
-mtune=native
会适得其反。
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;