• 关于Eigen库在Visual Studio2013中传参对齐报错问题


    一.错误如下

    具体问题及解决办法描述如下(引自http://www.fx114.net/qa-278-97757.aspx):
    英文提示:error C2719: 'p': formal parameter with __declspec(align('16')) won't be aligned
    中文提示:error C2719: “p”: 具有 __declspec(align('16')) 的形参将不被对齐导致整个现象的主要原因是使用了Eigen库,Eigen为了使用SSE加速,所以内存分配上使用了128位的指针。
    更加准确的说法:
    “First, "fixed-size" should be clear: an Eigen object has fixed size if its number of rows and its number of columns are fixed at compile-time. So for example Matrix3f has fixed size, but MatrixXf doesn't (the opposite of fixed-size is dynamic-size).
    The array of coefficients of a fixed-size Eigen object is a plain "static array", it is not dynamically allocated. For example, the data behind a Matrix4f is just a "float array[16]".
    Fixed-size objects are typically very small, which means that we want to handle them with zero runtime overhead -- both in terms of memory usage and of speed.
    Now, vectorization (both SSE and AltiVec) works with 128-bit packets. Moreover, for performance reasons, these packets need to be have 128-bit alignment.
    So it turns out that the only way that fixed-size Eigen objects can be vectorized, is if their size is a multiple of 128 bits, or 16 bytes. Eigen will then request 16-byte alignment for these objects, and henceforth rely on these objects being aligned so no runtime check for alignment is performed.”

    二.解决方案
    分为四种情况:
    Cause 1: Structures having Eigen objects as members
    Cause 2: STL Containers
    Cause 3: Passing Eigen objects by value
    Cause 4: Compiler making a wrong assumption on stack alignment (for instance GCC on Windows)
    每种情况可以对照官方的说法。可以参考如下链接
    http://eigen.tuxfamily.org/dox/TopicUnalignedArrayAssert.html
    在此不再重复表述。

    三.我的解决方法
    eigen 3.1.2有 bug, 重装Eigen;
    关闭使用 预编译头;
    关闭编译选项里面的16位对齐;
    把Eigen::Vector4f 传值改为 传引用 Eigen::Vector4f &;
    把结构体 传值 全部转换为 传引用。躲过对齐!!!

    编译器选项:C/C++ ---代码生成---结构图成员对齐;

    四.对stl vector 进行修改
    参照:http://blog.csdn.net/pkueecser/article/details/8602656
    产生问题的resize()方法,改为:
    void resize(size_type _Newsize, const _Ty & _Val)
    { // determine new length, padding with _Val elements as needed
    if (size() < _Newsize)
    _Insert_n(end(), _Newsize - size(), _Val);
    else if (_Newsize < size())
    erase(begin() + _Newsize, end());
    }
      注意其中红色部分,将传值改为传参,避免在参数栈上创建被对齐的结构的对象。然后,在我们使用std::vector< Foo<5, float> >之前包含我们的foo_vector.hpp头文件,就可以正常使用了。 注意红色部分.....

    本人参照第三点 把结构体 传值 全部转换为 传引用。躲过对齐!!! 结果如下:

  • 相关阅读:
    服务器建设问题
    JDBC --反射(二)
    Cookies
    http和https区别
    springboot常用注解
    线程池
    悲观锁和乐观锁
    java高并发下的数据安全
    idea解决mybatis逆向工程
    spring Cloud
  • 原文地址:https://www.cnblogs.com/yixu/p/5109936.html
Copyright © 2020-2023  润新知