• Eigen 向量化加速,对其导致崩溃问题 1. 解决策略


    Eigen 内由于断言失败而终止的打印信息类似如下

    program: path/to/eigen/Eigen/src/Core/DenseStorage.h:44:
    Eigen::internal::matrix_array<T, Size, MatrixOptions, Align>::internal::matrix_array()
    [with T = double, int Size = 2, int MatrixOptions = 2, bool Align = true]:
    Assertion `(reinterpret_cast<size_t>(array) & (sizemask)) == 0 && "this assertion
    is explained here: http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html
         READ THIS WEB PAGE !!! ****"' failed.
    

    Eigen 官方给出的解决地址:http://eigen.tuxfamily.org/dox/TopicUnalignedArrayAssert.html
    国内博客汉语版的翻译地址:https://blog.csdn.net/qq_27806947/article/details/105356401

    解决方式根据产生原因不同分为四类

    eigen类型是成员变量

    class Foo
    {
      //...
      Eigen::Vector2d v;
      //...
    };
    //...
    Foo *foo = new Foo;
    

    解决策略:Structures Having Eigen Members
    请注意,此处Eigen :: Vector2d仅用作示例,更一般而言,所有fixed-size vectorizable Eigen types都会出现此问题。

    STL容器或手动分配内存(new)

    如果您将stl容器(例如std::vector,std::map等)与Eigen对象或包含Eigen对象的类一起使用,

    std::vector<Eigen::Matrix2f> my_vector;
    struct my_class { ... Eigen::Matrix2f m; ... };
    std::map<int, my_class> my_map;
    

    那么您需要阅读以下单独的页面:STL容器与Eigen结合使用
    请注意,此处Eigen::Matrix2f仅用作示例,更一般而言,对于所有fixed-size vectorizable Eigen typesstructures having such Eigen objects as member,都会出现此问题。

    值传递eigen对象

    如果您代码中的某些函数正在通过值传递Eigen对象,例如这样,

    void func(Eigen::Vector4d v);
    

    那么您需要阅读以下单独的页面:将Eigen对象按值传递给函数

    编译器对堆栈对齐做出错误假设(例如Windows上的GCC)

    这是在Windows上使用GCC(例如MinGW或TDM-GCC)的人们的必读内容。If you have this assertion failure in an innocent function declaring a local variable like this:

    void foo()
    {
      Eigen::Quaternionf q;
      //...
    }
    

    then you need to read this separate page: Compiler making a wrong assumption on stack alignment.
    请注意,此处Eigen :: Quaternionf仅用作示例,更一般而言,所有fixed-size vectorizable Eigen types都会出现此问题。

    断言的一般解释

    fixed-size vectorizable Eigen types必须绝对在16字节对齐的位置创建,否则寻址它们的SIMD指令将崩溃。
    Eigen normally takes care of these alignment issues for you, by setting an alignment attribute on them and by overloading their "operator new".However there are a few corner cases where these alignment settings get overridden: they are the possible causes for this assertion.

    不在乎最佳矢量化,如何禁止向量优化

    三种可能性

    1. 使用Matrix,Array,Quaternion等对象的DontAlign选项会给您带来麻烦。这样,Eigen不会尝试对齐它们,因此不会承担任何特殊的对齐。On the down side, you will pay the cost of unaligned loads/stores for them, but on modern CPUs, the overhead is either null or marginal. See here for an example.
    2. Define EIGEN_DONT_ALIGN_STATICALLY . That disables all 16-byte (and above) static alignment code, while keeping 16-byte (or above) heap alignment. This has the effect of vectorizing fixed-size objects (like Matrix4d) through unaligned stores (as controlled by EIGEN_UNALIGNED_VECTORIZE), while keeping unchanged the vectorization of dynamic-size objects (like MatrixXd). But do note that this breaks ABI compatibility with the default behavior of static alignment.
    3. 或同时定义EIGEN_DONT_VECTORIZE和EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT。这样可以保留16字节的对齐代码,从而保留ABI兼容性,但完全禁用向量化
      如果您想知道为什么定义EIGEN_DONT_VECTORIZE本身并不能禁用16字节对齐和断言,则说明如下:
      它不会禁用断言,because otherwise code that runs fine without vectorization would suddenly crash when enabling vectorization. 它不会禁用16字节对齐,因为这将意味着矢量化和非矢量化的代码ABI不兼容。即使对于仅开发内部应用程序的人,这种ABI兼容性也非常重要,as for instance one may want to have in the same application a vectorized path and a non-vectorized path.
  • 相关阅读:
    TPM Key相关概念
    (转)eclipse报错及解决说明 "XX cannot be resolved to a type "
    (转)Bat Command
    (转)Linux下查看文件和文件夹大小 删除日志
    (转)每天一个linux命令(50):crontab命令
    (转)Vi命令详解
    (转)maven打包时跳过测试
    (转)mybatis常用jdbcType数据类型
    (转)MyBatis在插入的数据有空值时,可能为空的字段都要设置jdbcType
    (转)mybatis:动态SQL
  • 原文地址:https://www.cnblogs.com/flyinggod/p/13433452.html
Copyright © 2020-2023  润新知