visual-studio - 由于与 MSVC14 和 AVX 的未对齐访问而导致 Eigen 崩溃

标签 visual-studio crash alignment eigen avx

我有一段可以利用 SIMD 的代码。它在 Linux + GCC 上运行良好,但我已经将我的头撞到墙上一段时间了,因为当我使用启用了 AVX 的 MSVC 构建它时它崩溃了。

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 正确对齐,我有什么遗漏吗?

最佳答案

好吧,我想我已经深入了解了。我的代码检测运行时可用的 CPU 指令集,并动态地将执行分派(dispatch)给使用可用指令集的函数。我将使用不同 SIMD 指令的部分代码移动到不同的 TU 以使这成为可能。在我决定在直接使用 Eigen 的部分代码中打开矢量化之前,这可以正常工作。尽管每个 TU 都重新包含所有 Eigen,因此其内部值被相应地设置,但 Eigen 的分配器没有模板化并定义为内联。因此,编译器会合并 handmade_aligned_malloc 的所有定义。即使它们实际上并没有做同样的事情,也只进入一个函数,因为 EIGEN_DEFAULT_ALIGN_BYTES 的值在每个 TU 中根据设置的编译器标志而不同。它在 Linux 下与 GCC 一起工作的事实可能是偶然的。尽管我仍然需要为此找到适当的解决方案,但我相信这回答了导致崩溃的原因的问题。

关于visual-studio - 由于与 MSVC14 和 AVX 的未对齐访问而导致 Eigen 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50723121/

相关文章:

crash - Direct3D11取得最后错误

android - 启动新 Activity 时崩溃? ( Intent )

class - 在同一类构造函数中初始化静态std::vector <class>的问题

wpf - 在 listItem wpf 中将按钮右对齐

visual-studio - Visual Studio 黄色工具提示卡在屏幕上

visual-studio - VS 2008,分析多个测试

c - strstr() 在 gcc 和 VS 中的实现是否具有线性复杂度?

c# - visual studio c#远程调试关闭windows服务

javascript - 如何在 React Native 中使按钮居中

css - div的垂直中心不起作用