У меня есть следующий фрагмент кода, который может использовать SIMD.Он прекрасно работает в Linux + GCC, но я уже некоторое время бьюсь головой о стену, потому что он падает, когда я строю его с MSVC с включенным AVX.
template <>
void NewtonRaphson<double, InstructionSet::AVX>::initializeLu(const int elements)
{
std::cerr << "EDE " << EIGEN_DEFAULT_ALIGN_BYTES << "\n";
std::cerr << "Allocations are already aligned = " << EIGEN_MALLOC_ALREADY_ALIGNED << "\n";
m_luCalc = new Eigen::PartialPivLU<SolverMatrix<double>>(elements);
}
template <>
typename NewtonRaphson<double, InstructionSet::AVX>::TX const & NewtonRaphson<double, InstructionSet::FMA3>::ASolve()
{
m_iteration = 0;
m_stuckCounter = 0;
AInit();
// DOIT
std::cerr << "EDE WKR" << EIGEN_DEFAULT_ALIGN_BYTES << "\n";
std::cerr << "...WKR Allocations are already aligned = " << EIGEN_MALLOC_ALREADY_ALIGNED << "\n";
while (true)
{
// !2
ACalculateF(m_f, *m_px);
ACalculateJ(m_j, *m_px);
ZCalculateMeasures(m_f, m_fMin, m_fMax);
ZCalculateMeasures(m_dx, m_dxMin, m_dxMax); // 1
ZCheckStatus();
if (m_status != Status::CONTINUE)
return *m_px;
this->m_iteration++;
m_luCalc->compute(m_j);
m_dx = m_luCalc->solve(m_f);
*m_px -= m_dx;
};
return *m_px;
}
Код находится в отдельном месте.cpp файл, который скомпилирован с соответствующими флагами оптимизации.Сбой происходит в начале функции PartialPivLU :: compute ().Беглый взгляд на сборку, сгенерированную MSVC для функции-нарушителя, показывает следующее:
5D43D243 jle Eigen::PartialPivLU<Eigen::Matrix<double,-1,-1,0,-1,-1> >::compute<Eigen::Map<Eigen::Matrix<double,-1,-1,0,-1,-1>,32,Eigen::Stride<0,0> > >+0E9h (5D43D269h)
5D43D245 nop word ptr [eax+eax]
5D43D250 mov eax,dword ptr [ebp-1Ch]
5D43D253 vmovupd ymm0,ymmword ptr [eax+ecx*8]
5D43D258 vmovapd ymmword ptr [edi+ecx*8],ymm0
Сбой происходит по команде vmovapd
, которая пытается прочитать 16-байтовый выровненный адрес.EIGEN_DEFAULT_ALIGN_BYTES установлен на 32, а EIGEN_MALLOC_ALREADY_ALIGNED равен 0. Этот код работает нормально, когда я настраиваю оптимизацию SIMD на SSE2.
Есть ли что-то, чего мне не хватает для достижения правильного выравнивания с MSVC?