std::aligned_storage
std::aligned_storage的参数定义
- 第一个模板参数是storage的bytes大小
- 第二个模板参数是存储空间对齐的byte大小,且必须是2次幂
- std::aligned_storage创建一个raw 存储空间(没有确定类型),且按照第二个参数对齐;所以要使用的话,需要转化为实际的类型。
#include <type_traits>
using AlignedWorkspace = std::aligned_storage<1024, 128>::type;
AlignedWorkspace data;
float* ptr = reinterpret_cast<float*>(&data);
*ptr = 3.14f;
std::aligned_storage 使用实例
- oneflow工程中,在kernel优化过程中,将一些数据打包成一个pack,提高访存效率。
template <typename Type, int pack_size>
struct GetPackType {
using type = typename std::aligned_storage<pack_size * sizeof(Type),
pack_size * sizeof(Type)>::type;
};
template<typename Type, int pack_size>
using PackType = typename GetPackType<Type, pack_size>::type;
template <typename Type, int pack_size>
union Pack {
__device__ Pack() {}
PackType<Type, pack_size> storage;
Type element[pack_size];
};
alignas说明符
- 用于使得struct和class中member与特定字节边界对齐。
- 对齐大小必须是2的次幂
- alignas说明符的作用和使用:
- 根据硬件需要,进行对齐时使用
- 去避免padding,可以使struct最小化
- 对齐member到cache行的边界,这个在cpu优化过程中,避免cache行中由于没有对齐导致访存增加的问题。
- ABI兼容需要。
struct MyStruct {
int a;
alignas(16) float b;
char c;
int d;
};
struct MyStruct1 {
int a;
float b;
char c;
};
struct alignas(sizeof(int) * 4) MyStruct2 {
int a;
float b;
char c;
int d;
};
struct MyStruct3 {
int a;
alignas(16) float b;
char c;
long d;
};
struct MyStruct4 {
long a;
float b;
char c;
};
struct MyStruct5 {
int a;
long b;
char c;
};
struct MyStruct6 {
char a;
long b;
char c;
int d;
};
template <typename Type, int pack_size>
struct alignas(sizeof(Type) * pack_size) Packed {
__device__ Packed(){}
union {
Type elem[pack_size];
};
};