当前位置: 首页 > news >正文

Eigen 库EIGEN_MAKE_ALIGNED_OPERATOR_NEW详解和实战示例

在 Eigen 库中,EIGEN_MAKE_ALIGNED_OPERATOR_NEW 是一个用于确保对象在堆上创建时内存对齐的宏,特别适用于包含 Eigen 向量或矩阵成员变量的类。


为什么需要它?

Eigen 的 SIMD 优化要求某些类型(如 Vector4f, Matrix4d 等)必须按 16 字节对齐(即内存地址是 16 的倍数),以满足 CPU 向量化指令的要求。
在栈上(stack)定义的变量通常自动满足这一要求,但在堆上动态分配对象(如 new MyClass())时,如果不特殊处理,默认的 new 操作可能返回未对齐内存地址,从而导致程序崩溃或性能下降。


解决办法:使用 EIGEN_MAKE_ALIGNED_OPERATOR_NEW

这是一个宏,作用是:

在类中重载 operator newoperator delete,以确保该类实例在堆上的分配满足 Eigen 所需的对齐要求(16 字节对齐)。


使用方式

#include <Eigen/Core>class MyClass
{
public:EIGEN_MAKE_ALIGNED_OPERATOR_NEWEigen::Vector3d pos;Eigen::Matrix3d rot;
};

正确使用:

MyClass obj1;                  // 栈上分配 ✔️ 不需要特别对齐
MyClass* obj2 = new MyClass(); // 堆上分配 ✔️ 由于使用了宏,满足对齐

如果不加宏会怎样?

如果你的类中包含例如 Eigen::Vector3d, Matrix4d 等需要对齐的数据类型,但你没有使用 EIGEN_MAKE_ALIGNED_OPERATOR_NEW,则:

  • 栈上分配一般没问题(编译器自动对齐)。
  • 堆上分配很可能发生崩溃 或性能下降,因为 new 分配的内存可能没有按 16 字节对齐。

实现细节(展开宏)

在 Eigen 头文件中,该宏定义类似如下:

#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW \EIGEN_NEW_ALIGN_OVERRIDE \static void* operator new(size_t size) { return Eigen::aligned_malloc(size); } \static void operator delete(void * ptr) { Eigen::aligned_free(ptr); }

它本质上调用了:

  • Eigen::aligned_malloc(size) 分配对齐内存
  • Eigen::aligned_free(ptr) 回收对齐内存

注意事项

  • 若你的类将作为 std::vector<MyClass> 使用,也需要配合:

    std::vector<MyClass, Eigen::aligned_allocator<MyClass>>
    

    否则 vector 默认分配器可能造成未对齐的问题。

  • C++17 后 new 默认会对齐到 alignof(T),但仍推荐使用该宏以兼容性和安全起见,尤其在旧版本编译器或第三方库中。


实战场景应用

下面是一个包含 EIGEN_MAKE_ALIGNED_OPERATOR_NEW小型 C++ 示例项目,展示如何正确创建一个包含 Eigen::Vector3d 成员变量的类,并安全地在堆上分配它,同时在 std::vector 中使用对齐分配器避免崩溃。


项目结构

aligned_example/
├── CMakeLists.txt
└── main.cpp

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(AlignedEigenExample)set(CMAKE_CXX_STANDARD 14)
find_package(Eigen3 REQUIRED)add_executable(aligned_example main.cpp)
target_link_libraries(aligned_example Eigen3::Eigen)

main.cpp

#include <iostream>
#include <vector>
#include <Eigen/Dense>// 示例类,包含 Eigen 向量成员
class Pose
{
public:EIGEN_MAKE_ALIGNED_OPERATOR_NEWEigen::Vector3d position;Eigen::Quaterniond orientation;Pose(double x, double y, double z): position(x, y, z), orientation(Eigen::Quaterniond::Identity()) {}void print() const {std::cout << "Position: " << position.transpose() << std::endl;}
};int main() {std::cout << "=== 堆上分配 ===" << std::endl;Pose* p1 = new Pose(1.0, 2.0, 3.0);p1->print();delete p1;std::cout << "\n=== std::vector 中使用对齐分配器 ===" << std::endl;std::vector<Pose, Eigen::aligned_allocator<Pose>> poses;poses.emplace_back(4.0, 5.0, 6.0);poses.emplace_back(7.0, 8.0, 9.0);for (const auto& p : poses) {p.print();}return 0;
}

输出示例

=== 堆上分配 ===
Position: 1 2 3=== std::vector 中使用对齐分配器 ===
Position: 4 5 6
Position: 7 8 9

小结

场景是否需要 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
类中包含 Eigen 对齐类型
类仅包含标量或不对齐类型
仅在栈上使用类对象可选
会堆上分配或使用 STL 容器如 vector强烈建议使用

http://www.lqws.cn/news/517465.html

相关文章:

  • 数据结构?AVL树!!!
  • 【树的概念及其堆的实现】
  • 复用对象Aspose.Words 中 DocumentBuilder 的状态管理解析
  • Encoder-only PLM RoBERTa ALBERT (BERT的变体)
  • HuggingFace下载的模型缓存到了C盘,如何安全迁移到其他盘
  • sql 多表联查返回不为空的字段 COALESCE
  • 11 MySQL 如何优化数据查询方案?
  • 入门级STM32F103C8T6无人机遥控(原理图)
  • 打造灵活强大的PDF解析管道:从文本提取到智能分块的全流程实战
  • Systemd服务配置:开启自启Jar应用全指南
  • 【请关注】实操mongodb集群部署
  • 教育培训教学通用PPT模版
  • 【图论题典】Swift 解 LeetCode 最小高度树:中心剥离法详解
  • linux内核奔溃转储之kexec、kdump
  • 【ArcGIS】水资源单项评价
  • github 图床使用免费CDN加速(jsdelivr)
  • 【版本控制教程】如何使用Unreal Engine 5 + UE源代码控制(Perforce P4)
  • NPU介绍
  • SQL学习笔记2
  • Python Matplotlib绘图指南,10分钟制作专业级数据可视化图表
  • Django
  • 力扣网C语言编程题:位运算来解决 “寻找重复数”
  • 用css实现文字字体颜色渐变
  • SpringMVC系列(三)(请求处理的十个实验(上))
  • CLIP中学习“少样本线性探针”(Few-shot Linear Probe)学习笔记
  • 完成国产化替代!昆明卷烟厂用时序数据库 TDengine 重塑工业时序数据平台
  • Odoo API 集成:XML-RPC 与 JSON-RPC 的比较
  • WinUI3_设置原生态标题栏样式
  • 9.11 Indoor localization based on factor graphs: A unified framework
  • OCR表格识别效果对比