前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言中字节对齐问题分析2

C语言中字节对齐问题分析2

作者头像
随心助手
发布2020-05-12 15:32:44
1.5K0
发布2020-05-12 15:32:44
举报
文章被收录于专栏:nginx遇上redis

2. 为什么要字节对齐

简单的说来就是为了提高cpu的性能,或者说是为了提高程序运行的效率。当然,在其背后更有简化cpu设计的功效。因此,我们写的c程序为了获得更高的运行效率就必须最大限度的满足cpu对于字节对齐的要求,编译器在其中起着至关重要的作用。

下面的c程序在编译后运行,在终端将会打出”size of type_t is 8”。为什么是8而不是5呢?这是因为编译器考虑到了运行效率,从而将type_t做了4字节对齐的处理。

代码语言:javascript
复制
#include<studio.h>
typedef struct
{
       char a;
       int b;
}type_t;
int main()
{
       printf(“size of type is:%d”,sizeof(type_t));
       return 0;
}

这里需要指出的是,编译器会根据具体的结构选择是4字节对齐还是2字节对齐。比如,下面定义的element_t结构,其中sizeof大小应当是4,而不是3,更不会是8。

代码语言:javascript
复制
typedef struct
{
       char a;
       short b;
}element_t;

下面我们来分析为什么进行字节对齐能提高运行效率。要对数据结构进行更为高效的操作,从cpu的角度就是尽可能减少对内存的访问次数 。对于type_t结构,其内存布局如图1所示,需要指出的是SPARC是big-endian模式,图中b=b0b1b2b3.

在做进一步的分析之前,还需要清除的是,对于32位处理器,其数据总线是32位的。

因此,cpu从内存中存取数据时可以(也只能)一次读入4字节。为此,cpu从内存中存取数据时总是以4字节为边界进行存取的。如果,我们所写的程序只需要访问内存中的一个字节,此时也需要从内存读入4个字节吗?是的。对于一次内存所存取的4个字节中,我们是需要存取其中的一个字节、两个字节或者全部4个字节,cpu如何区分呢?答案是,cpu提供了不同的指令,而由编译器根据情况选择使用不同的指令。

现在,我们开始分析采用字节对齐和不采用字节对齐时,cpu 对于内存的访问次数有何不同。回到图1,先看看采用字节对齐时的情况,从图中可以看出,当cpu需要分别访问a变量和b变量时,无论如何都只需要分别进行一次内存存取,图中的花括号表示一次 内存存取操作。对于不采用字节对齐的情况,a变量无论如何只要进行一次内存操作的,而b变量有可能需要进行二次内存操作,因为这一变量跨越了4字节的边界。这里之所以说是可能,是因为有可能对b进行访问之前,可能刚好完成了对于a的访问,而对a访问时,b0、b1和b2也同时读入(或写入)了,这种情况下,只需要读入(或写入)b3即可。

此外,更为麻烦的是对于边界不对齐的b,还得将其合成4字节(一部分是来自一个四字节中的b0、b1和b2,另一部分来自另一个4字节中的b3),而这又增加了程序的复杂性,即需要更多的指令来完成。

以上分析可以看出,采用字节对齐能提高系统性能。而编译器在编译程序时,也会根据需要选择不同的指令来完成对数据的存取操作。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nginx遇上redis 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档