eigen 由于-match=native 使用不一致导致的coredump

问题描述

当用户代码和库代码没有同时使用编译选项 -march=native时,在运行时经常会报 double free error或者其他的内存相关错误。但是在某些时候,这个编译选项又不会带来错误。
经过更多测试,发现这个问题发生在接口类存在Eigen数组作为成员变量的时候。因此需要对这个问题进行原理理解。

太长不看(解决方法)

接口类当中的eigen成员变量都声明不做对齐,这样就解决了用户代码和库编译时指令集加速方式不一致时带来的不同对齐方式的冲突。如,使用Eigen::Matrix<float, 2, 1, Eigen::DontAlign> 取代Eigen::Vector2f

Eigen内存对齐

eigen内存需要额外的对齐,进而才能使用eigen调用的各类加速指令集等。因此,动态、静态的eigen矩阵,包含eigen的结构体、类,都需要额外的对齐命令才能正常工作(构造、运算、析构)。
详情见:
http://eigen.tuxfamily.org/dox/group__DenseMatrixManipulation__Alignement.html
目前影响我们的部分有:

  1. EIGEN_MAKE_ALIGNED_OPERATOR_NEW 与 C++17:C++17中,自动对包含eigen类、结构体的构造函数进行对齐的操作,因此 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 宏此时为空
  2. 固定大小的eigen矩阵默认会进行16位对齐(有指令集加速时表现可能不一致!!!见下一节)
  3. 作为类成员变量的动态大小的eigen矩阵不影响类本身的构造和析构;但是动态大小的eigen矩阵本身的构造和析构仍然有自己的对齐问题(见指令集加速)
  4. 将eigen矩阵传值进入函数是非常不好的方式。效率和内存正确性都可能受影响。建议使用常量引用、Eigen::Ref或者Eigen::Map等复制成本极低的方式
cmake_minimum_required(VERSION 2.8.3) project(fast_livo) set(CMAKE_BUILD_TYPE "Release") message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # Set common compile options set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -fexceptions") # Specific settings for Debug build set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g") # Detect CPU architecture message(STATUS "Current CPU architecture: ${CMAKE_SYSTEM_PROCESSOR}") # Specific settings for Release build if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm|aarch64|ARM|AARCH64)") if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") # 64-bit ARM optimizations (e.g., RK3588 and Jetson Orin NX) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -mcpu=native -mtune=native -ffast-math") message(STATUS "Using 64-bit ARM optimizations: -O3 -mcpu=native -mtune=native -ffast-math") else() # 32-bit ARM optimizations with NEON support set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -mcpu=native -mtune=native -mfpu=neon -ffast-math") message(STATUS "Using 32-bit ARM optimizations: -O3 -mcpu=native -mtune=native -mfpu=neon -ffast-math") endif() add_definitions(-DARM_ARCH) else() # x86-64 (Intel/AMD) optimizations set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -march=native -mtune=native -funroll-loops") #-flto message(STATUS "Using general x86 optimizations: -O3 -march=native -mtune=native -funroll-loops") add_definitions(-DX86_ARCH) endif() # Define project root directory add_definitions(-DROOT_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/\") # Detect CPU core count for potential multithreading optimization include(ProcessorCount) ProcessorCount(N) message(STATUS "Processor count: ${N}") # Set the number of cores for multithreading if(N GREATER 4) math(EXPR PROC_NUM "4") add_definitions(-DMP_EN -DMP_PROC_NUM=${PROC_NUM}) message(STATUS "Multithreading enabled. Cores: ${PROC_NUM}") elseif(N GREATER 1) math(EXPR PROC_NUM "${N}") add_definitions(-DMP_EN -DMP_PROC_NUM=${PROC_NUM}) message(STATUS "Multithreading enabled. Cores: ${PROC_NUM}") else() add_definitions(-DMP_PROC_NUM=1) message(STATUS "Single core detected. Multithreading disabled.") endif() # Check for OpenMP support find_package(OpenMP QUIET) if(OpenMP_CXX_FOUND) message(STATUS "OpenMP found") add_compile_options(${OpenMP_CXX_FLAGS}) else() message(STATUS "OpenMP not found, proceeding without it") endif() # Check for mimalloc support find_package(mimalloc QUIET) if(mimalloc_FOUND) message(STATUS "mimalloc found") else() message(STATUS "mimalloc not found, proceeding without it") endif() # Find catkin and required dependencies find_package(catkin REQUIRED COMPONENTS geometry_msgs nav_msgs sensor_msgs roscpp rospy std_msgs pcl_ros tf message_generation eigen_conversions vikit_common vikit_ros cv_bridge image_transport ) find_package(Eigen3 REQUIRED) find_package(PCL REQUIRED) find_package(OpenCV REQUIRED) find_package(Sophus REQUIRED) find_package(Boost REQUIRED COMPONENTS thread) set(Sophus_LIBRARIES libSophus.so) # Define the catkin package catkin_package( CATKIN_DEPENDS geometry_msgs nav_msgs roscpp rospy std_msgs message_runtime cv_bridge vikit_common vikit_ros image_transport DEPENDS EIGEN3 PCL OpenCV Sophus ) # Include directories for dependencies include_directories( ${catkin_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIR} ${PCL_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${Sophus_INCLUDE_DIRS} include ) # Add libraries add_library(vio src/vio.cpp src/frame.cpp src/visual_point.cpp) add_library(lio src/voxel_map.cpp) add_library(pre src/preprocess.cpp) add_library(imu_proc src/IMU_Processing.cpp) add_library(laser_mapping src/LIVMapper.cpp) # Add the main executable add_executable(fastlivo_mapping src/main.cpp) # Link libraries to the executable target_link_libraries(fastlivo_mapping laser_mapping vio lio pre imu_proc ${catkin_LIBRARIES} ${PCL_LIBRARIES} ${OpenCV_LIBRARIES} ${Sophus_LIBRARIES} ${Boost_LIBRARIES} ) # Link mimalloc if found if(mimalloc_FOUND) target_link_libraries(fastlivo_mapping mimalloc) endif() 逐行详细解释一下
07-29
这段 CMakeLists.txt 文件用于配置一个名为 `fast_livo` 的 ROS 项目,包含多个库和一个主可执行文件。下面是对每一行的逐行详细解释: --- ```cmake cmake_minimum_required(VERSION 2.8.3) ``` 指定构建该项目所需的最低 CMake 版本为 2.8.3。 ```cmake project(fast_livo) ``` 定义项目名称为 `fast_livo`。 ```cmake set(CMAKE_BUILD_TYPE "Release") ``` 设置默认的构建类型为 Release(发布模式)。 ```cmake message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") ``` 输出当前构建类型信息。 ```cmake set(CMAKE_CXX_STANDARD 17) ``` 启用 C++17 标准。 ```cmake set(CMAKE_CXX_STANDARD_REQUIRED ON) ``` 要求编译器必须支持 C++17。 ```cmake set(CMAKE_CXX_EXTENSIONS OFF) ``` 禁用编译器特定的 C++ 扩展。 ```cmake set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -fexceptions") ``` 添加通用的编译选项:启用多线程(`-pthread`)和异常支持(`-fexceptions`)。 ```cmake set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g") ``` 在 Debug 模式下,禁用优化(`-O0`)并生成调试信息(`-g`)。 ```cmake message(STATUS "Current CPU architecture: ${CMAKE_SYSTEM_PROCESSOR}") ``` 输出当前系统的 CPU 架构。 ```cmake if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm|aarch64|ARM|AARCH64)") ``` 如果 CPU 架构是 ARM 或 AArch64,则启用 ARM 相关优化。 ```cmake set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -mcpu=native -mtune=native -ffast-math") ``` 在 64 位 ARM 架构下启用高性能编译优化选项。 ```cmake message(STATUS "Using 64-bit ARM optimizations: -O3 -mcpu=native -mtune=native -ffast-math") ``` 输出优化信息。 ```cmake set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -mcpu=native -mtune=native -mfpu=neon -ffast-math") ``` 在 32 位 ARM 架构下启用 NEON 支持的优化。 ```cmake add_definitions(-DARM_ARCH) ``` 定义宏 `ARM_ARCH`,用于代码中判断是否为 ARM 架构。 ```cmake set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -march=native -mtune=native -funroll-loops") ``` 在 x86/x86_64 架构下启用通用优化选项。 ```cmake add_definitions(-DX86_ARCH) ``` 定义宏 `DX86_ARCH`,表示当前为 x86 架构。 ```cmake add_definitions(-DROOT_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/\") ``` 定义宏 `ROOT_DIR`,指向项目根目录。 ```cmake include(ProcessorCount) ProcessorCount(N) ``` 包含并调用 ProcessorCount 模块,获取 CPU 核心数量。 ```cmake message(STATUS "Processor count: ${N}") ``` 输出检测到的 CPU 核心数。 ```cmake if(N GREATER 4) ``` 如果核心数大于 4,则限制为 4 线程。 ```cmake math(EXPR PROC_NUM "4") ``` 设置线程数为 4。 ```cmake add_definitions(-DMP_EN -DMP_PROC_NUM=${PROC_NUM}) ``` 启用多线程宏定义,并设置线程数。 ```cmake message(STATUS "Multithreading enabled. Cores: ${PROC_NUM}") ``` 输出多线程启用信息。 ```cmake elseif(N GREATER 1) ``` 如果核心数大于 1 但小于等于 4,则使用全部核心。 ```cmake add_definitions(-DMP_EN -DMP_PROC_NUM=${PROC_NUM}) ``` 同样启用多线程宏定义。 ```cmake message(STATUS "Multithreading enabled. Cores: ${PROC_NUM}") ``` 输出启用信息。 ```cmake else() ``` 否则为单核。 ```cmake add_definitions(-DMP_PROC_NUM=1) ``` 强制线程数为 1。 ```cmake message(STATUS "Single core detected. Multithreading disabled.") ``` 输出单核提示。 ```cmake find_package(OpenMP QUIET) ``` 尝试查找 OpenMP 支持。 ```cmake if(OpenMP_CXX_FOUND) ``` 如果找到 OpenMP。 ```cmake add_compile_options(${OpenMP_CXX_FLAGS}) ``` 添加 OpenMP 编译选项。 ```cmake message(STATUS "OpenMP found") ``` 输出提示信息。 ```cmake else() ``` 如果没有找到 OpenMP。 ```cmake message(STATUS "OpenMP not found, proceeding without it") ``` 输出提示信息。 ```cmake find_package(mimalloc QUIET) ``` 尝试查找 mimalloc 内存分配器。 ```cmake if(mimalloc_FOUND) ``` 如果找到 mimalloc。 ```cmake message(STATUS "mimalloc found") ``` 输出提示信息。 ```cmake else() ``` 否则。 ```cmake message(STATUS "mimalloc not found, proceeding without it") ``` 输出提示信息。 ```cmake find_package(catkin REQUIRED COMPONENTS ...) ``` 查找 catkin 及其依赖包。 ```cmake find_package(Eigen3 REQUIRED) ``` 查找 Eigen3。 ```cmake find_package(PCL REQUIRED) ``` 查找 Point Cloud Library (PCL)。 ```cmake find_package(OpenCV REQUIRED) ``` 查找 OpenCV。 ```cmake find_package(Sophus REQUIRED) ``` 查找 Sophus 库。 ```cmake find_package(Boost REQUIRED COMPONENTS thread) ``` 查找 Boost 线程库。 ```cmake set(Sophus_LIBRARIES libSophus.so) ``` 手动指定 Sophus 的库文件。 ```cmake catkin_package(...) ``` 定义 catkin 包及其依赖。 ```cmake include_directories(...) ``` 添加头文件搜索路径。 ```cmake add_library(vio src/vio.cpp src/frame.cpp src/visual_point.cpp) ``` 创建一个名为 vio 的静态库。 ```cmake add_library(lio src/voxel_map.cpp) ``` 创建一个名为 lio 的静态库。 ```cmake add_library(pre src/preprocess.cpp) ``` 创建一个名为 pre 的静态库。 ```cmake add_library(imu_proc src/IMU_Processing.cpp) ``` 创建一个名为 imu_proc 的静态库。 ```cmake add_library(laser_mapping src/LIVMapper.cpp) ``` 创建一个名为 laser_mapping 的静态库。 ```cmake add_executable(fastlivo_mapping src/main.cpp) ``` 创建主可执行文件 fastlivo_mapping。 ```cmake target_link_libraries(fastlivo_mapping ...) ``` 将所有库和依赖链接到可执行文件。 ```cmake if(mimalloc_FOUND) target_link_libraries(fastlivo_mapping mimalloc) endif() ``` 如果找到 mimalloc,则将其链接到可执行文件。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值