nginx源码分析--内存对齐处理

本文介绍了Nginx中内存对齐的重要性,包括内存池的内存地址对齐和长度2的幂取整,以及内存对齐的理论。讲解了通用内存对齐的原理,如数据项存储在地址与数据项大小的整数倍位置,以及编译器和操作系统的默认对齐系数。文章还讨论了Nginx如何通过宏实现内存对齐,确保CPU缓存的高效读写,提高性能。
摘要由CSDN通过智能技术生成

1.nginx内存对齐主要是做2件事情:

1) 内存池的内存地址对齐;

2) 长度按照2的幂取整.因为前面结构体已经是对齐了,如果后面的内存池每一小块不是2的幂,那么后面的就不能对齐


2.通用内存对齐理论

内存对齐数据项只能存储在地址是数据项大小的整数倍的内存位置上

例如int类型占用4个字节,地址只能在0,4,8等位置上。


数据的对齐(alignment)

指数据的地址和由硬件条件决定的内存块大小之间的关系。一个变量的地址是它大小的倍数的时候,这就叫做自然对齐(naturally aligned)。例如,对于一个32bit的变量,如果它的地址是4的倍数,-- 就是说,如果地址的低两位是0,那么这就是自然对齐了。所以,如果一个类型的大小是2n个字节,那么它的地址中,至少低n位是0。对齐的规则是由硬件引起的。一些体系的计算机在数据对齐这方面有着很严格的要求。在一些系统上,一个不对齐的数据的载入可能会引起进程的陷入。在另外一些系统,对不对齐的数据的访问是安全的,但却会引起性能的下降。在编写可移植的代码的时候,对齐的问题是必须避免的,所有的类型都该自然对齐。


预对齐内存的分配

在大多数情况下,编译器和C库透明地帮你处理对齐问题。POSIX 标明了通过malloc( ), calloc( ), 和realloc( ) 返回的地址对于任何的C类型来说都是对齐的。在Linux中,这些函数返回的地址在32位系统是以8字节为边界对齐,在64位系统是以16字节为边界对齐的。有时候,对于更大的边界,例如页面,程序员需要动态的对齐。虽然动机是多种多样的,但最常见的是直接块I/O的缓存的对齐或者其它的软件对硬件的交互,因此,POSIX 1003.1d提供一个叫做posix_memalign( )的函数


2.1对较小结构体进行机器字对齐--避免多次读

对于现代计算机硬件来说,内存只能通过特定的对齐地址(比如按照机器字)进行访问。举个例子来说,比如在64位的机器上,不管我们是要读取第0个字节还是要读取第1个字节,在硬件上传输的信号都是一样的。因为它都会把地址0到地址7,这8个字节全部读到CPU,只是当我们是需要读取第0个字节时,丢掉后面7个字节,当我们是需要读取第1个字节,丢掉第1个和后面6个字节。
当我们要读取的字节刚好落在两个机器字内时,就出现两次访问内存的情况,同时通过一些逻辑计算才能得到最终的结果。

因此,为了更好的提升性能,我们须尽量将结构体做到机器字(或倍数)对齐,而结构体中一些频繁访问的字段也尽量安排在机器字对齐的位置。


操作系统的默认对齐系数
每个操作系统都有自己的默认内存对齐系数,如果是新版本的操作系统,默认对齐系数一般都是8,因为操作系统定义的最大类型存储单元就是8个字节,例如 long long,不存在超过8个字节的类型(例如int是4,char是1,long在32位编译时是4,64位编译时是8)。当操作系统的默认对齐系数与第一节所讲的内存对齐的理论产生冲突时,以操作系统的对齐系数为基准。


编译器是按照什么样的原则进行对齐的。首先有3个重要的概念:自身对齐值,指定对齐值和有效对齐值。
 
自身对齐值:即数据类型的自身的对齐值。例如char型的数据,其自身对

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值