深入理解ngx_align_ptr宏及内存管理

来源:互联网 发布:helpdesk软件 编辑:程序博客网 时间:2024/04/29 14:26

http://blog.csdn.net/cywosp/article/details/7044288

 

nginx 内存池的内存地址对齐和长度按照2的幂取整

内存池的里面返回的地址,都是经过对齐处理的,这样使用这个对齐的地址比如做memcpy的时候,不用跨cache line 性能更好吧。

又学了一招。

 

看看使用的代码

http://trac.nginx.org/nginx/browser/nginx/trunk/src/core/ngx_palloc.c

 

 

 

#ifndef NGX_ALIGNMENT
#define NGX_ALIGNMENT   sizeof(unsigned long)    /* platform word */
#endif

#define ngx_align(d, a)     (((d) + (a - 1)) & ~(a - 1))
#define ngx_align_ptr(p, a)                                                   \
    (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))

 

先分析  (((d) + (a - 1)) & ~(a - 1))表达式
理解表达式  ~(a - 1)注意,其中a为2的幂,设右数第n位为非零位,则a-1为右数的n-1位均为1, 则有~(a-1)为最后的n-1位全为0;

显然可得一个数和2的幂进行  减一取反再按位与操作,即为该数减去(其与a求余的值)

这种计算地址或者长度对齐,取整的宏还是很有用的。cpu访问对齐的数据较快,不对齐的的int之类的,有可能区要多次内存访问才能取到值。

 

向上取整倍数,ngx_align内存对齐的宏,对于a,传入CPU的二级cache的line大小,通过ngx_cpuinf函数,可以获得ngx_cacheline_size的大小,一般intel为64或128

计算宏ngx_align(1, 64)=64,只要输入d<64,则结果总是64,如果输入d=65,则结果为128,以此类推。

进行内存池管理的时候,对于小于64字节的内存,给分配64字节,使之总是cpu二级缓存读写行的大小倍数,从而有利cpu二级缓存取速度和效率。

ngx_cpuinfo函数实际是调用了汇编代码,获取cpu二级缓存大小!

 

//==================================================

上面式子,当a等于2的幂的时候,比如,4,8,16等值时,

d加上(a-1) 之后的值肯定要比最小的a的倍数要大的。因为a为2的幂,所以(a - 1) 刚好后面几位都是连续的1,取反之后再相与一下之后,就把小于a的余数部分丢掉了。 不过如果a不是2的幂,比如a=3, d=1 ,那么推算一下,上面的计算就不成立了。


   这种计算地址或者长度对齐,取整的宏还是很有用的。cpu访问对齐的数据跟快把,不对齐的的int之类的,有可能区要多次内存访问才能取到值出来。 写个简单的字符串内存池,AllocateString时打算把所有的字符串放到一个连续的内存块上,觉得还是把长度取整一下比较好。这样后续的对字符串的memcpy就是内存字对齐,更好吧。

 

//=================================================

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击