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

LLVM 数据结构简介

LLVM 数据结构简介

  • LLVM 数据结构简介
    • ArrayRef
      • 特点
      • 与标准库 array 对比
    • SmallVector
      • 与标准库 vector 的对比

LLVM 数据结构简介

ArrayRef

llvm::ArrayRef 是一个轻量级的只读容器,主要用于引用一段连续的内存区域。它的设计目标是提供高效的数据访问,而不需要拥有底层数据的所有权。这使得 ArrayRef 特别适合在函数参数中按值传递,从而避免了不必要的内存拷贝。

特点

  • 只读:ArrayRef 不能修改其引用的数据,也不能添加新元素(另一个容器 MutableArrayRef 可以修改)。
  • 轻量级:它只存储一个指向数据的指针和数据的长度,而不存储实际的数据,所以拷贝时非常高效。
  • 按值传递:在传递 ArrayRef 时,实际上传递的是一个指针和其指向数据的长度,所以不需要再对其按引用传递。
  • 操作一致:它的大多数操作,与 STL array 保持一致。

与标准库 array 对比

  • 所有权:llvm::ArrayRef 不拥有其引用数据的所有权,只是对数据的引用;std::array 拥有数据的所有权,存储在栈上。
  • 大小:llvm::ArrayRef 容量是动态的,可以引用任意长度的数组。但由于数组长度是静态的,所以从程序角度看,ArrayRef 的具体引用类型,容量是确定的;std::array 大小在编译期间固定,和 C 数组一样。
  • 可变性:llvm::ArrayRef 是只读的,不能修改引用数据;std::array 允许修改其元素,提供完整的读写权限。
  • 初始化:llvm::ArrayRef 的初始化更灵活,可以从 C 数组、std::array,std::vector 或其他顺序容器初始化。std::array 只能从初始化列表或在定义时使用构造函数初始化。
  • 性能:llvm::ArrayRef 适合在高频传递参数时使用。std::array 默认按值拷贝,会带来开销,需要指定其引用类型作为参数类型。如果是 constexpr 修饰,编译器可以优化传参性能。
template <typename T>class ArrayRef {
private:const T* data = nullptr;size_t length = 0;
}

SmallVector

SmallVector是llvm中自定义的一种通用数据结构,在llvm的各层次间都可以使用。SmallVector与std::Vector非常类似 ,支持迭代、push_back、pop_back,以及随机存取元素。

SmallVector对与元素较少的情况时性能是优与std::vector的。 这是因为SmallVector使用了一种比较通用的局部缓存设计模式,减少了malloc/free的巨大开销。

std::vector会调用malloc函数申请一块内存用于放置元素,std::array是对内置数组的一个封装,因此其存放元素的数组会与std::array放置在同一个位置。如果std::array是在栈上声明的,那么其存放元素的数组也位于栈上。

内存的位置不同导致了std::array与std::vector效率的不同。因为std::vector是通过malloc申请的堆内存,而std::array是栈内存。

堆内存的申请需要调用系统函数分配内存,这个开销是巨大的。相比之下,栈内存几乎是零开销,因为值需要调整栈指针。当然std::array也并不总是在栈上的,取决与你分配它的方式。但是任然会比std::vector少分配一次堆内存。
smallvector的本质就是当元素个数少的时候像std::array一样将存储元素的内存放在类里面,当元素个数多的时候像std::vector一样分配堆内存。这样就兼具了两者的优点。 这种操作被称为局部缓存设计模式,在llvm很多地方都有体现

template<typename T, unsigned N = CalculateSmallVectorDefaultInlinedElements<T>::value> 
class SmallVector;

llvm::SmallVector 是一个可变长数组,类似于 std::vector,同时它对较小长度的数组做了优化。它的内存管理方式采用局部缓存的设计思路,在对象内部预留一小块空间,用于存储数据。当数据量超出预留空间的大小时,才会将数据放在堆上。它本身保存一部分元素,这便使得在小数组中,避免进行堆分配的操作,提高了效率。

注意到,它带有一个含默认值的模板参数 N,它用来指定预留空间的大小,默认不指定时,编译器会自动选择一个合理的阈值(通常考虑依据是栈空间的占用情况)。

与标准库 vector 的对比

  • 性能优势:在数据量较小时,由于不会涉及到堆内存分配和管理的开销,性能会优于 std::vector。另外,它可以识别平凡可复制的特性,从而更细粒度地做内存管理
  • 退化时的性能损失:当发生从栈到堆的退化时,llvm::SmallVector 会带来数据拷贝的开销。所以需要仔细考虑阈值的设定。
  • 可能浪费空间:llvm::SmallVector 会在定义时预分配设定的 N 的空间,如果实际数据少于 N,那么会存在空间浪费的问题。std::vector 也存在类似问题。
    在这里插入图片描述

SmallVector,它继承了SmallVectorImpl和SmallVectorStorage。SmallVector本身只有一系列构造函数(拷贝构造、赋值构造等),没有成员变量,具体的一些成员函数放在SmallVectorImpl中,存储元素的数组放在SmallVectorStorage中。 SmallVectorStorage类中直接声明了一个数组。

/// Storage for the SmallVector elements.  This is specialized for the N=0 case
/// to avoid allocating unnecessary storage.
template <typename T, unsigned N>
struct SmallVectorStorage { // alignas(T) 强制编译器为 InlineElts 数组分配内存时,其起始地址必须满足 T 类型的对齐要求。// 确保 InlineElts 这个原始字节数组的起始地址满足类型 T 的内存对齐要求,// 从而使得后续我们可以安全地在此数组的内存上直接构造 T 类型的对象,// 避免因内存未对齐而导致的未定义行为alignas(T) char InlineElts[N * sizeof(T)];//在 C++11 中,标准库提供了 std::aligned_storage 来专门处理这种情况//std::aligned_storage_t<sizeof(T), alignof(T)> InlineElts[N];
};

拥有小型缓冲区优化

这个数组会和对象放在同一块内存,当需要存放的元素较少时就可以放在这个数组中,避免了调用malloc产生巨大的开销。


文章转载自:

http://MBnRgBrH.nqfxq.cn
http://IE8LlGSm.nqfxq.cn
http://582R5ThY.nqfxq.cn
http://Uq81W6jG.nqfxq.cn
http://PNdpZ8jz.nqfxq.cn
http://3cHjQwp9.nqfxq.cn
http://53mvNAkW.nqfxq.cn
http://YfDHIRhc.nqfxq.cn
http://vG1ex1T2.nqfxq.cn
http://EQgvhrRo.nqfxq.cn
http://lXBU4Neg.nqfxq.cn
http://5niJJwZD.nqfxq.cn
http://yBgF1Os1.nqfxq.cn
http://JiyGYwSy.nqfxq.cn
http://CViw34xq.nqfxq.cn
http://YLeFuBfB.nqfxq.cn
http://H8UGWCDP.nqfxq.cn
http://VmS4Vw1A.nqfxq.cn
http://5cBNtfhV.nqfxq.cn
http://ENiGs1jV.nqfxq.cn
http://KSv6HZLz.nqfxq.cn
http://3dHiV0KE.nqfxq.cn
http://vdbgCpcp.nqfxq.cn
http://IO6fu4fU.nqfxq.cn
http://lgV7wo8N.nqfxq.cn
http://wORAu0f0.nqfxq.cn
http://IoJhH5Fd.nqfxq.cn
http://pmnDejmv.nqfxq.cn
http://EOeKQdT1.nqfxq.cn
http://mqqAXTxi.nqfxq.cn
http://www.dtcms.com/a/374396.html

相关文章:

  • MCP与http、websocket的关系
  • 【modbus学习】
  • 【linux】sed/awk命令检索区间日志
  • 瑞派虹泰环城总院 | 打造“一站式宠物诊疗空间”,定义全国宠物医疗新高度
  • 数据分析画图显示中文
  • 嵌入式ARM架构学习3——启动代码
  • 2025云计算趋势:Serverless与AI大模型如何赋能中小企业
  • 如何利用 AWS 服务器优化跨境电商和 SEO 战略?
  • 大数据毕业设计-基于Python的中文起点网小说数据分析平台(高分计算机毕业设计选题·定制开发·真正大数据)
  • 小程序开发单行日历可滑动
  • 项目日记 -日志系统 -搭建基础框架
  • 计算机网络第四章(4)——网络层《ARP协议》
  • 探迹SalesGPT
  • 带有 Attention 机制的 Encoder-Decoder 架构模型分析
  • 利用易语言编写,逻辑为按照数字越大抽取率越前
  • leetcode 219 存在重复元素II
  • Redis(缓存)
  • ARP 协议
  • 169.在Vue3中使用OpenLayers + D3实现地图区块呈现不同颜色的效果
  • 【C++】递归与迭代:两种编程范式的对比与实践
  • 【Java】设计模式——单例、工厂、代理模式
  • C++ ——一文读懂:Valgrind 检测内存泄漏
  • 代码随想录算法训练营第三十一天 | 合并区间、单调递增的数字
  • Redis核心通用命令深度解析:结合C++ redis-plus-plus 实战指南
  • 三防手机的三防是指什么?推荐一款实用机型
  • 请求库-axios
  • Python 2025:AI工程化与智能代理开发实战
  • 聚铭网络入选数世咨询《中国数字安全价值图谱》“日志审计”推荐企业
  • 【56页PPT】数字化智能工厂总体设计SRMWCSWMSMESEMS系统建设方案(附下载方式)
  • 高性价比云手机挑选指南