Boost库学习笔记(三)内存对齐模块

简介: Boost库学习笔记(三)内存对齐模块

Boost库学习笔记(三)内存对齐模块

一、模块简介

Boost.Align本模块主要的功能是提供一系列的函数、类、模板、特性和宏等来控制、审查和诊断内存对齐

二、基本原理

1. 动态分配

C++11为class类型添加了增长对齐类型(over-alignment),但是C++标准库中的new运算符、表达式和默认的分配器、std::allocator并不支持为over-aligned的数据动态分配内存。boost提供库来提供函数和分配器来支持over-aligned的数据。

aligned_free(pointer)

代替了::operator delete(pointer, std::nothrow)

aligned_allocator<T>

代替了std::allocator<T>

aligned_allocator_adaptor<Allocator>

代替了 Allocator的使用

aligned_delete

代替了std::default_delete<T>

2. 指针对齐

C++11标准提供了std::align来对齐指针的值,但是(libstdc++直到gcc4.8.0)并没有支持实现,msvc11.0错误的实现了它,Boost库实现了这些,为C++03编译器也提供了std::align

3. 查询对齐

C++11标准库提供了std::alignment_of的特性来查询对齐所需的类型,但是直到libc++(clang3.4),并没有为数组的类型正确的提供,在msvc14.0中会给数组类型返回错误的值。Boost库实现了这些,为C++03编译器也提供了实现。

4.提示对齐

分配对齐的内存有时不足以确保生成最佳代码。开发人员使用特定的编译器内在函数来通知编译器内存块的给定对齐属性。该库提供了一个宏 , BOOST_ALIGN_ASSUME_ALIGNED来为具有适当内在函数的编译器抽象该功能。

5. 检查对齐

该库提供了一个函数,is_aligned 用于测试指针值的对齐情况。在断言中验证内存是否正确对齐通常很有用。

三、API

align

包含头文件: boost/align/align.hpp

功能: 对齐一块内存并返回首地址(指针对齐)

接口:

void* align(std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space)

输入参数:

  • alignment 应当为2的幂,为存储空间对齐的边界值。
  • size 为对齐内存的长度
  • ptr 为对齐内存后的起始内存地址指针
  • space 为对齐内存后的占用大小(长度)

以alignment为对齐边界申请连续size字节的内存,ptr输入时是起始地址,处理完之后是对齐之后的内存空间首地址,space会减少本来偏移的空间字节数(因为ptr不一定正好在以alignment指定的对齐边界上,故需要做偏移)。

实例:

#include <iostream>
#include <boost/align/align.hpp>
int main(int argc, char** argv) {
  void* stroge;
  size_t space = 5000;
    //按512字节对齐的方式,开辟2000个连续的空间,stroge最初值为0xcccccccccccccccc,本身没有在对齐边界上,需要偏移308个字节地址达到边界,space相应减少308,开辟2000个字节的内存地址,space至少能满足2308的大小。返回的地址就是0xccccccccccccce00,newPtr与stroge的值都是此
  void* newPtr = boost::alignment::align(512, 2000, stroge, space);
  return 0;
}

align_up

包含头文件: <boost/align/align_up.hpp>

功能: 返回一个大于等于value的对齐边界(alignment)倍数的值。

接口:

template<class T> constexpr T align_up(T value, std::size_t alignment) noexcept;

输入参数:

  • 输入任意值value
  • 输入2的幂对齐边界alignment

输出参数:

  • 上边界的值

align_down

包含头文件: <boost/align/align_down.hpp>

功能: 返回一个小于等于value的对齐边界(alignment)倍数的值。

接口:

template<class T> constexpr T align_up(T value, std::size_t alignment) noexcept;

输入参数:

  • 输入任意值value
  • 输入2的幂对齐边界alignment

输出参数:

  • 下边界的值

实例:

#include <iostream>
#include <boost/align/align.hpp>
#include <boost/align/align_up.hpp>
#include <boost/align/align_down.hpp>
int main(int argc, char** argv) {
  size_t bound = 567;
    //输出1024
  size_t retUp = boost::alignment::align_up(bound, 512);
    //输出512
  size_t retDown = boost::alignment::align_down(bound, 512);
  return 0;
}

aligned_alloc

包含头文件: <boost/align/aligned_alloc.hpp>

功能: 分配指定对齐方式的连续内存

接口:

void* aligned_alloc(std::size_t alignment, std::size_t size);

输入参数

  • 对齐方式alignment(2的幂)
  • 连续内存的字节数size

返回

  • 开辟的内存的首地址

aligned_free

包含头文件: <boost/align/aligned_alloc.hpp>

功能: 释放对齐内存指针

接口:

void aligned_free(void* ptr);

输入参数

  • 开辟的对齐指针ptr

返回

is_aligned

包含头文件: <boost/align/is_aligned.hpp>

功能: 判断某指针指向的连续空间是否按照指定的对齐方式对齐。

接口:

bool is_aligned(const volatile void* ptr, std::size_t alignment) noexcept;
template<class T> constexpr bool is_aligned(T value, std::size_t alignment) noexcept;

输入参数

  • 开辟的对齐指针ptr或者指定值,指定的对齐方式

返回

  • true or false

实例:

#include <iostream>
#include <boost/align/align.hpp>
#include <boost/align/aligned_alloc.hpp>
#include <boost/align/is_aligned.hpp>
int main(int argc, char** argv) {
  void* storage = boost::alignment::aligned_alloc(32, 1000);
  if (boost::alignment::is_aligned(storage, 32)) {
    boost::alignment::aligned_free(storage);
  }
  return 0;
}

四、相关类

1. aligned_allocator

包含头文件: <boost/align/aligned_allocator.hpp>

构造函数:

aligned_allocator() = default;
template<class U> aligned_allocator(const aligned_allocator<U, Alignment>&) noexcept;

成员函数:

pointer allocate(size_type size, const_void_pointer = 0);

返回size * sizeof(T)的存储空的地址首指针,分配不了抛出std::bad_alloc的异常

void deallocate(pointer ptr, size_type);

释放指针ptr引用的空间

size_type max_size() const noexcept;

返回调用allocate()的参数最大值

2. aligned_allocator_adaptor

包含头文件: <boost/align/aligned_allocator_adaptor.hpp>

构造函数:

aligned_allocator_adaptor() = default;
//使用Allocator的基类std::forward<A>(alloc)初始化
template<class A> aligned_allocator_adaptor(A&& alloc) noexcept;
template<class U> aligned_allocator_adaptor(const aligned_allocator_adaptor<U, Alignment>& other) noexcept;

成员函数:

Allocator& base() noexcept;

返回对象的分配器指针

const Allocator& base() const noexcept;

返回常量对象的分配器指针

pointer allocate(size_type size);

返回一段连续的大小为size * sizeof(value_type)的连续内存空间,对齐方式为指定的最小对齐方式和默认值类型对齐方式的较大者。

pointer allocate(size_type size, const_void_pointer hint);

返回一段连续的大小为size * sizeof(value_type)的连续内存空间,对齐方式为指定的最小对齐方式和默认值类型对齐方式的较大者。hint是通过调用allocate()获得指针。

void deallocate(pointer ptr, size_type size);

通过指针释放空间。

3. aligned_delete

包含头文件: <boost/align/aligned_delete.hpp>

成员运算符:

template<class T> void operator()(T* ptr) noexcept(noexcept(ptr->~T()));

功能: 利用析构函数调用aligned_free()将参数指针释放。

五、traits

alignment_of

template<class T> struct alignment_of;

包含头文件: <boost/align/alignment_of.hpp>

参考值说明:

T是类模板,需要T作为一个整数常量代表类型的size(std::size_t),T是一个引用数组类型时,要求数组是对齐存储的,而且元素值也是对齐类型的。

六、宏断言

BOOST_ALIGN_ASSUME_ALIGNED

包含头文件: <boost/align/assume_aligned.hpp>

定义:

BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment)

功能: 断言ptr的内存空间是否按要求对齐

七、官方使用列举

//1.对齐空间分配
//alignment对齐边界  2的幂
//size 字节数
void* storage = boost::alignment::aligned_alloc(alignment, size);
//释放空间
boost::alignment::aligned_free(storage);
//2.对齐分配器allocator
//遵循over-alignment的分配
std::vector<int128_t, boost::alignment::aligned_allocator<int128_t> > vector;
//指定动态分配的最小对齐边界的范例
std::vector<double, boost::alignment::aligned_allocator<double, 64> > vector;
//3.对齐内存分配器适配器
//将分配器类转换成适配器对象,遵循over-alignment对齐方式
boost::alignment::aligned_allocator_adaptor<First> second(first);
//为动态分配指定最小的对齐方式值
boost::alignment::aligned_allocator_adaptor<First, 64> second(first);
//4.对齐删除器
//一个删除器应该与aligned_alloc成对使用
std::unique_ptr<double, boost::alignment::aligned_delete> pointer;
//5.指针对齐
//算法起始指针,返回对齐后的地址指针
void* pointer = storage;
//给定的空间
std::size_t space = size;
void* result = boost::alignment::align(64, sizeof(double), pointer, space);
//6.查询对齐
//编译期间获知是否根据给定类型对齐
boost::alignment::alignment_of<int128_t>::value
//7.宏断言对齐
BOOST_ALIGN_ASSUME_ALIGNED(pointer, 64)
//8.条件检查对齐
assert(boost::alignment::is_aligned(pointer, 64));
相关文章
|
6月前
|
C语言
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
|
6月前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
83 0
|
12月前
|
Oracle 关系型数据库 Linux
解决在linux服务器上部署定时自动查找cpu,内存,磁盘使用量,并将查询结果写入数据库的脚本,只能手动运行实现插库操作
问题描述:将脚本名命名为mortior.sh(以下简称mo),手动执行脚本后查询数据库,表中有相应的信息,放入自动执行队列中,脚本被执行,但是查询数据库,并没有新增数据。
80 0
|
C语言
【进阶C语言】字符串与内存库函数认识与模拟实现(1)
size_t为无符号整形,接受他的返回值的变量类型也应该为size_t 函数参数就是字符指针类型。const为了修饰*str,防止原字符串的数据被修改。 需要包含的头文件为:#include&lt;string.h&gt;
56 0
【深入理解计算机系统】int 不是整数 | float 不是实数 | 内存引用错误的例子 | 学习笔记
【深入理解计算机系统】int 不是整数 | float 不是实数 | 内存引用错误的例子 | 学习笔记
71 0
|
19天前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
1月前
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
34 2
|
6月前
|
存储 算法 C语言
C库函数详解 - 内存操作函数:memcpy()、memmove()、memset()、memcmp() (一)
`memcpy()` 和 `memmove()` 是C语言中的两个内存操作函数。 `memcpy()` 函数用于从源内存区域复制指定数量的字节到目标内存区域。它不处理内存重叠的情况,如果源和目标区域有重叠,结果是未定义的。函数原型如下: ```c void *memcpy(void *dest, const void *src, size_t num); ```
214 6
|
2月前
|
安全 C++
超级好用的C++实用库之环形内存池
超级好用的C++实用库之环形内存池
44 5
|
2月前
|
C++
超级好用的C++实用库之动态内存池
超级好用的C++实用库之动态内存池
29 0