Недопустимая инструкция при компиляции с -mfma - PullRequest
0 голосов
/ 26 апреля 2018

Я компилирую с GCC 5.3.0 на Intel SandyBridge E5-2670. Когда я использую эти флаги -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 или, скорее всего, я ее неправильно использовал?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Для отладки недопустимой инструкции вы должны прежде всего взглянуть на разборку, а не на обратный след или исходный код. В вашем случае, однако, даже из исходного кода вы можете легко увидеть, что неправильная ( недопустимая ) команда имеет вид vfmadd231pd, что относится к расширению набора команд FMA. Но процессоры SandyBridge, один из которых у вас есть, не поддерживают это расширение ISA, поэтому, включив его в компиляторе, вы попали себе в ногу.

В Linux вы можете проверить, поддерживает ли ваш процессор FMA, с помощью этой команды оболочки:

grep -q '\<fma\>' /proc/cpuinfo && echo supported || echo not supported
0 голосов
/ 26 апреля 2018

-mfma добавляет набор команд FMA к набору разрешенных инструкций. Для этого вам потребуется как минимум процессор Intel-Haswell или AMD-Piledriver.

Добавление -m InstructionSet дополнительно к -march=native никогда не поможет - либо оно уже включено, либо позволит компилятору использовать недопустимые инструкции (на вашем ЦП).

...