We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在课堂上黄老师的讲授中,我们学习了很多关于提高运行效率的操作,例如移动赋值,对流运算符的引用等,C++中,字节对齐是提高运行效率的一个重要手段语言中,特别是对于结构体而言。
1、内容 现代计算机中内存空间都是按照byte划分的,其实计算机在访问特定类型变量的时候经常在特定的内存地址访问,为了进一步提高访问效率,就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
2.原因 需要字节对齐的根本原因在于CPU访问数据的效率问题。假设上面整型变量的地址不是自然对齐,比如为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002-0x00000003的一个short,第二次取从0x00000004-0x00000005的一个short然后组合得到所要的数据,如果变量在0x00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为char,然后组合得到整型数据。 而如果变量在自然对齐位置上,则只要一次就可以取出数据。 另外字节对齐的作用不仅是便于cpu快速访问,同时合理的利用字节对齐也可以有效地节省存储空间。 也即CPU一次访问时,要么读0x01~0x04,要么读0x05~0x08硬件不支持一次访问就读到0x02~0x05 例:如果0x02~0x05存了一个int,读取这个int就需要先读0x01~0x04,留下0x02~0x04的内容,再读0x05~0x08,留下0x05的内容,两部分拼接起来才能得到那个int的值,这样读一个int就要两次内存访问,效率就低了。
3.具体操作 如果在编程的时候要考虑节约空间的话,那么我们只需要假定结构的首地址是0,然后各个变量按照上面的原则进行排列即可,基本的原则就是把结构中的变量按照类型大小从小到大声明,尽量减少中间的填补空间,还有一种就是为了以空间换取时间的效率,我们显示的进行填补空间进行对齐,比如:有一种使用空间换时间做法是显式的插入reserved成员:
struct A{ char a; char save[3]; //时空互为代价 int b; }
save成员对我们的程序没有什么意义,它只是起到填补空间以达到字节对齐的目的(其实即使不加这个成员通常编译器也会给我们自动填补对齐)
4.隐患 代码中关于对齐的隐患,很多是隐式的,比如在强制类型转换的时候,例如:
unsigned int i = 0x12000000; unsigned char *p = NULL; unsigned short *p1 = NULL; p = &i; *p = 0x00; p1 = (unsigned short *)(p + 1); *p1 = 0x0000;
这样最后两句代码,从奇数边界去访问unsigned short型变量,显然不符合对齐的规定,在x86上,类似的操作只会影响效率,但是在一些其它系统上可能会报错。
在VC系统中,关于字节对齐有着更为细节的实现,感兴趣的同学可参阅https://www.cnblogs.com/blueoverflow/p/4712355.html
The text was updated successfully, but these errors were encountered:
No branches or pull requests
在课堂上黄老师的讲授中,我们学习了很多关于提高运行效率的操作,例如移动赋值,对流运算符的引用等,C++中,字节对齐是提高运行效率的一个重要手段语言中,特别是对于结构体而言。
1、内容
现代计算机中内存空间都是按照byte划分的,其实计算机在访问特定类型变量的时候经常在特定的内存地址访问,为了进一步提高访问效率,就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
2.原因
需要字节对齐的根本原因在于CPU访问数据的效率问题。假设上面整型变量的地址不是自然对齐,比如为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002-0x00000003的一个short,第二次取从0x00000004-0x00000005的一个short然后组合得到所要的数据,如果变量在0x00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为char,然后组合得到整型数据。
而如果变量在自然对齐位置上,则只要一次就可以取出数据。
另外字节对齐的作用不仅是便于cpu快速访问,同时合理的利用字节对齐也可以有效地节省存储空间。
也即CPU一次访问时,要么读0x01~0x04,要么读0x05~0x08硬件不支持一次访问就读到0x02~0x05
例:如果0x02~0x05存了一个int,读取这个int就需要先读0x01~0x04,留下0x02~0x04的内容,再读0x05~0x08,留下0x05的内容,两部分拼接起来才能得到那个int的值,这样读一个int就要两次内存访问,效率就低了。
3.具体操作
如果在编程的时候要考虑节约空间的话,那么我们只需要假定结构的首地址是0,然后各个变量按照上面的原则进行排列即可,基本的原则就是把结构中的变量按照类型大小从小到大声明,尽量减少中间的填补空间,还有一种就是为了以空间换取时间的效率,我们显示的进行填补空间进行对齐,比如:有一种使用空间换时间做法是显式的插入reserved成员:
4.隐患
代码中关于对齐的隐患,很多是隐式的,比如在强制类型转换的时候,例如:
这样最后两句代码,从奇数边界去访问unsigned short型变量,显然不符合对齐的规定,在x86上,类似的操作只会影响效率,但是在一些其它系统上可能会报错。
在VC系统中,关于字节对齐有着更为细节的实现,感兴趣的同学可参阅https://www.cnblogs.com/blueoverflow/p/4712355.html
The text was updated successfully, but these errors were encountered: