Colderleo's blog Colderleo's blog
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)

Colder Leo

热爱代码的打工人
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)
  • bug定位的一些情形
  • c++性能调优,可能的情况
  • total-编程知识点集锦
  • hpc_common.hpp
  • memory order 内存模型
  • 类型推导之auto-template-decltype
  • 完美转发forward源码分析
  • 左值和右值,右值引用、重载 std-move,引用折叠
  • cmake用法
  • alignas、alignof、sizeof实现内存对齐分配
    • alignas、alignof、
      • 地址对齐
      • alignas用法
  • 通过宏定义控制debug打印
  • 程序耗时性能测试
  • 线程池开源项目阅读
  • C++类中包含没有默认构造函数的成员
  • C++可变参数模板
  • C++属性继承 public protected private
  • C++智能指针
  • C++导出so的方法,以及extern C 注意事项
  • 四种spin lock
  • condition_variable和unique_lock
  • dpdk、kernel bypass
  • 智能网卡solarflare、Mellanox、X10等
  • 汇编寄存器和常见指令
  • c++ 类的静态成员变量未定义
  • C++获取类成员函数地址
  • preload示例
  • C++异常安全和RAII
  • C++11单例模式
  • C++歪门邪道
  • boost-program-option用法
  • c++17通过模板获取类成员的个数
  • 通过模板实现结构体成员拷贝-按成员名匹配
  • STL学习路径
  • boost库安装使用方法
  • C++文件读写
  • linux下socket通信demo,server和client
  • makefile写法
  • RxCpp
  • C++
gaoliu
2021-10-23
目录

alignas、alignof、sizeof实现内存对齐分配

# alignas、alignof、

sizeof实现内存对齐分配

# 什么时候需要 posix_memalign

https://stackoverflow.com/questions/6410609/when-do-we-need-to-use-posix-memalign-instead-of-malloc (opens new window)

malloc 在32位上分配8字节对齐,在64位上16字节对齐。 但是当需要更多更大的对齐方式时就用到了,比如4K-aligned

对一个类型为T的对象数组分配内存,且满足其内存对齐要求:

// - 分配大小为sizeof(T) * n
// - 对齐方式为alignof(T)
T *p;
posix_memalign(reinterpret_cast<void **>(&p), alignof(T), sizeof(T) * n);

// 或者:
typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;
1
2
3
4
5
6
7

注意typename指示一个类型名,而非定义一个类型,以下声明了一个T::iterator类型的变量itr,其中T是一个模板实例化时才知道的类:

    typename T::iterator itr;
1

如果没有typename指示,T::iterator会被认为是T的静态变量,而不是类型名。

typename关键字不会定义一个类型,如果你想定义一个新类型的话,你必须这样:

typedef typename T::iterator ITR;
1

下面是一个AlignedAllocator的示例

#if defined(__cpp_aligned_new)
template <typename T> using AlignedAllocator = std::allocator<T>;
#else
template <typename T> struct AlignedAllocator {
  using value_type = T;

  T *allocate(std::size_t n) {
    if (n > std::numeric_limits<std::size_t>::max() / sizeof(T)) {
      throw std::bad_array_new_length();
    }
#ifdef _WIN32
    auto *p = static_cast<T *>(_aligned_malloc(sizeof(T) * n, alignof(T)));
    if (p == nullptr) {
      throw std::bad_alloc();
    }
#else
    T *p;
    if (posix_memalign(reinterpret_cast<void **>(&p), alignof(T),
                       sizeof(T) * n) != 0) {
      throw std::bad_alloc();
    }
#endif
    return p;
  }

  void deallocate(T *p, std::size_t) {
#ifdef _WIN32
    _aligned_free(p);
#else
    free(p);
#endif
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 地址对齐

  • 优点:提高性能 假设计算机的字大小为4个字节(32位),CPU每次只能对4的倍数内存地址进行读取, 如果一个4字节的变量其地址是4的倍数,那么cpu一次就可以读出来。如果不是4的倍数,那就要读两次。

  • 默认结构体的对齐方式: https://blog.csdn.net/u011404495/article/details/54837797 (opens new window)

    假设首变量地址为0,其内部成员的地址是自身对齐长度的整数倍。

  • 禁用对齐

      struct pkg_hdr {
        uint32_t len;
        uint32_t code;
        uint8_t  type;
      } __attribute__((packed));
    
    1
    2
    3
    4
    5

# alignas用法

参考: https://zouzhongliang.com/index.php/2019/07/07/c11xinzengalignasguanjianzizuoyong/ (opens new window)

#include <string>
#include <iostream>
using namespace std;

struct struct_Test1 { char c; int i; double d; };
struct struct_Test2 { char c; double d; int i; };

struct alignas(16) struct_a16 
{ char c; int i; double d; //inner same as test1 };

struct alignas(32) struct_a32
{ char c; int i; double d; //inner same as test1 };

int main()
{
    struct_Test1 test1;
    struct_Test2 test2;
    struct_a16 a16;
    struct_a32 a32;

    cout << "char alignment:" << alignof(char) << endl;     //1
    cout << "int alignment:" << alignof(int) << endl;       //4
    cout << "double alignment:" << alignof(double) << endl; //8

    cout << "test1 size:" << sizeof(test1) << endl;         //16
    cout << "test2 size:" << sizeof(test2) << endl;         //24        
    cout << "test1 alignment:" << alignof(test1) << endl;   //8
    cout << "test2 alignment:" << alignof(test2) << endl;   //8
    
    cout << "a16 alignment:" << alignof(a16) << endl;   //16
    cout << "a32 alignment:" << alignof(a32) << endl;   //32
    cout << "a16 size:" << sizeof(a16) << endl;         //16
    cout << "a32 size:" << sizeof(a32) << endl;         //32

    system("pause");
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
编辑 (opens new window)
上次更新: 2023/05/07, 17:27:54
cmake用法
通过宏定义控制debug打印

← cmake用法 通过宏定义控制debug打印→

最近更新
01
通过模板实现结构体成员拷贝-按成员名匹配
05-07
02
c++17通过模板获取类成员的个数
05-01
03
avx-sse切换惩罚
04-30
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Colder Leo | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×