关于数据对齐和填充的另一个困惑
Yet another confusion about data alignment and padding
我一直在读关于数据对齐和结构填充的文章。我从这里开始,只是为了表达我的理解,我可以说T
类型的元素或数据e
是自然对齐的,如果它的地址a
是它的数据大小[sizeof T
]的倍数,
让我们考虑
struct test{
short a;
char b;
};
由于struct test
的最大排列(short
(,constexpr auto size = sizeof test
为4
然后我来到这里,第一个答案很好地解释了数据对齐,作者使用了这个例子
data1: "ab"
data2: "cdef"
|a b c d| |e f 0 0|
假设内存访问粒度为4字节,我将在这里假设data1
是2
字节,data2
是4 byte
,因为data2
从奇数地址开始,或者它的地址不是4 byte
的倍数,这被认为是未对齐的数据,所以访问data2
将根据体系结构产生不同的效果。
这里有填充,通过添加junkies(或纯0(使data2
自然对齐,最后我们有
|a b 0 0| |c d e f|
到目前为止还可以,现在让我们将这两个数据包装到一个结构中
struct wrap{
data1: "ab"
data2: "cdef"
};
现在,通过考虑最大对齐,wrap
大小将变为具有两字节填充的8
。
在这里,在struct wrap
的情况下,无论是有填充还是没有填充,处理器实际上需要两个周期(给定WORD大小为4字节(来获取wrap
对象,对吗?那么我们为什么需要填充呢?
无填充:
|a b c d| |e f 0 0|
假设处理器获取了8字节的wrap object
,data1
是两个字节,因此它可以保存"ab",剩余的将被截断(就像填充位将被截断的方式一样(并且data2
可以从其地址(读取"cdef"(读取连续的4个字节,其余的都被截断了,那么为什么我们需要在这里填充,或者我只是弄错了?
第二个问题或多或少类似于上述
struct test2{
short a; //2 byte
char _3,_4,_5,_6,_7,_8,_9,_10,_11 ;
};
sizeof test2
将给出12,如果现在内存访问粒度(更改WORD=8(是8字节,那么test2
的对象将占用两个WORD,无论是否填充,它都将占用两次WORD,所以无论test2
的对齐如何,都需要两个周期来获取其对象,如果是这种情况,为什么填充在这里很重要?为什么12而不是11都需要在8字节的边界中有两个循环?
最后一个问题,
struct final{
char a;
int b;
};
假设struct final
被打包(没有对齐(,vartest::b
将被放置在奇数地址
记忆(只是一种理论表示(
0 1 2 3 4 5 6 7
tets::a:1 test::b:1 test::b:2 test::b:3 test::b:4
test::b:x
am此处不是指位字段
我已经了解到,只要我通过`.使用对象访问test::b。或者->'它会很好,但当我把它的地址
int * p = &(test::b) ; (void)*p;
此语句要么性能受损,要么崩溃。
同样,如果WORD=8字节,那么struct final
的对象将在一个周期内进入内存,假设指针p
保持地址1
,这是奇数,但难道仅仅是*p
的差异就不能将从地址1
开始到其指向元素类型(4字节(的位复制到内存中吗?为什么这里有问题?我错过了什么?
数据错位的问题与整个结构的加载/存储无关。它显示时可以访问各个字段。
当字段未对齐时,需要两次读/写加上字节重排,而不是一次。填充结构更大,我们不介意。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 运行同一解决方案的另一个项目的项目
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- C++从另一个类访问公共静态向量的正确方法是什么
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 使用std::transform将一个范围的元素添加到另一个范围中
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- C++试图读取一个文件并输出到另一个文本文件
- 如何在 c++ 上将一定大小的数组填充到另一个更大大小的数组中?
- 关于数据对齐和填充的另一个困惑
- 填充另一个 2D 数组后,堆已损坏
- 用另一个容器中的迭代器填充容器
- 用另一个元组中的元素填充一个元组
- C++指向在另一个结构内部的结构中定义的变量(由用户填充)
- 用另一个QList填充QList
- C++函数来填充一个 std::vector 基于另一个 std::vector 的内容?