在存储的时候,为了提高效率,一般都会让偏移量落在2的m次方的位置上,而且常有向上取整和向下取整两种需求。
向下取整
PALIGN_DOWN(x,align)  (x & (- align))
 
这样做为什么可以,因为align 取反 还是自己,只是高位全变成1了,然后再和原来的数&运算,此时不对齐多出来的1都被清0了。
PALIGN_UP(x,align) (-(-x) & (-align))
原理也比较容易推断,将x变成负数,那么对-x 向下取反,得到的数是向下取反的负数,但是再加一个负号,负负得正,获得了一个更大的整数
实现了向上取整。
相当于 PALIGN_UP(x,align) =====> -PALIGN_DOWN(-x,align)

PALIGN_DOWN向下取整例子:

4二进制:

0000 0100

1111 1100

如果x是3, 011,和-align相与后为0

如果x是5,101,相与后是4.

一篇文章:

内存对齐算法

字节对齐是在分配内存时需要考虑的问题,两个小算法:

(1)最容易想到的算法:

  1. unsigned int calc_align(unsigned int n,unsigned align)
  2. {
  3. if ( n / align * align == n)
  4. return n;
  5. return  (n / align + 1) * align;
  6. }

(2)更好的算法:

  1. unsigned int calc_align(unsigned int n,unsigned align)
  2. {
  3. return ((n + align - 1) & (~(align - 1)));
  4. }

对于2算法原理如下:

2字节对齐,要求地址位为2,4,6,8...,要求二进制位最后一位为0(2的1次方)
4字节对齐,要求地址位为4,8,12,16...,要求二进制位最后两位为0(2的2次方)
8字节对齐,要求地址位为8,16,24,32...,要求二进制位最后三位为0(2的3次方)
16字节对齐,要求地址位为16,32,48,64...,要求二进制位最后四位为0(2的4次方)
...
由此可见,我们只要对数据补齐对齐所需最少数据,然后将补齐位置0就可以实现对齐计算。
 
(1)(align-1),表示对齐所需的对齐位,如:2字节对齐为1,4字节为11,8字节为111,16字节为1111...
(2)(x+(align-1)),表示x补齐对齐所需数据      
(3)&~(align-1),表示去除由于补齐造成的多余数据
(4) (x+(align-1))&~(align-1),表示对齐后的数据
 
举个例子:如8字节对齐。起始地始是6
6 + (8 - 1)=0000 0110 + 0000 0111 = 0000 1101
0000 1101 & ~(0000 0111) = 0000 1000  //去除由于补齐造成的多余数据
 

2的m次方 内存对齐的更多相关文章

  1. struct内存对齐1:gcc与VC的差别

    struct内存对齐:gcc与VC的差别 内存对齐是编译器为了便于CPU快速访问而采用的一项技术,对于不同的编译器有不同的处理方法. Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则:  ...

  2. c/c++中内存对齐完全理解

    一,什么是内存对齐?内存对齐用来做什么? 所谓内存对齐,是为了让内存存取更有效率而采用的一种编译阶段优化内存存取的手段. 比如对于int x;(这里假设sizeof(int)==4),因为cpu对内存 ...

  3. C++内存对齐总结

    大家都知道,C++空类的内存大小为1字节,为了保证其对象拥有彼此独立的内存地址.非空类的大小与类中非静态成员变量和虚函数表的多少有关. 而值得注意的是,类中非静态成员变量的大小与编译器内存对齐的设置有 ...

  4. C/C++: C++位域和内存对齐问题

    1. 位域: 1. 在C中,位域可以写成这样(注:位域的数据类型一律用无符号的,纪律性). struct bitmap { unsigned a : ; unsigned b : ; unsigned ...

  5. C/C++ 知识点1:内存对齐

    预备知识:基本类型占用字节 在32位操作系统和64位操作系统上,基本数据类型分别占多少字节呢? 32位操作系统: char : 1    int :4    short : 2    unsigned ...

  6. Windows+GCC下内存对齐的常见问题

    结构/类对齐的声明方式 gcc和windows对于modifier/attribute的支持其实是差不多的.比如在gcc的例子中,内存对齐要写成: class X { //... } __attrib ...

  7. c++内存对齐

    内存对齐原则: 1.数据成员对齐规则:struct, union的数据成员,第一个数据成员放在offset为0的地方,之后的数据成员的存储起始位置都是放在该数据成员大小的整数倍位置.如在32bit的机 ...

  8. C语言中内存对齐

    今天一考研同学问我一个问题,一个结构体有一个int类型成员和一个char类型成员,问我这个结构体类型占多少个字节,我直接编个程序给他看结果.这个结构体占八个字节,咦,当时我蛮纳闷的,一个int类型四个 ...

  9. 内存对齐 和 sizeof小结

    数据对齐(内存对齐)指该数据所在的地址必须是该数据长度的整数倍.X86CPU能直接访问对齐的数据,当它试图访问未对齐的数据时,会在内部进行一系列的调整,降低运行速度.数据对齐一般出现在结构体和类中,在 ...

随机推荐

  1. Java单链表的实现

    将结点Node进行封装,假设Node的操作有增加,删除,查找,打印几个操作.将Node实现为链表Link的内部类,简化代码. package Chapter5; import java.securit ...

  2. JAVA的覆盖、继承和多态的详细解说.this和super的用法

    1. 继承: (1)子类的构造方法一定会调用父类的构造方法. (2)任何子类构造方法第一行肯定是this();或者super();两个择一. this();调用本类的其它构造方法.(传递相应参数调用相 ...

  3. Python - 素数筛

    def shai(n): prim = list() check = list([1] * (n + 1)) for i in range(2, n + 1): if(check[i] == 1): ...

  4. SpringMVC 基于注解的Controller详解

    本文出处 http://blog.csdn.net/lufeng20/article/details/7598801 概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spri ...

  5. PHP5 mysqli 教程

    mysqli提供了面向对象和面向过程两种方式来与数据库交互,分别看一下这两种方式. 1.面向对象 在面向对象的方式中,mysqli被封装成一个类,它的构造方法如下: __construct ([ st ...

  6. iOS简单排序--字母排序、NSDictionary排序

    // 数组用系统方法compare做字母的简单排序 NSArray *oldArray = @[@"bac",@"bzd",@"azc",@ ...

  7. AGS API for JavaScript 图表上地图

    原文:AGS API for JavaScript 图表上地图 图1 图2 图3 -------------------------------------华丽丽的分割线--------------- ...

  8. Ubuntu 12.04+DarwinStreamingSrvr6.0.3 架设流媒体服务器

    1.安装Ubuntu 12.04操作系统,网上很多教程.. 2.打开终端,下载darwin源代码DarwinStreamingSrvr6.0.3-Source.tar,补丁patch dss-6.0. ...

  9. The Beginner’s Guide to iptables, the Linux Firewall

    Iptables is an extremely flexible firewall utility built for Linux operating systems. Whether you’re ...

  10. An Implementation of Double-Array Trie

    Contents What is Trie? What Does It Take to Implement a Trie? Tripple-Array Trie Double-Array Trie S ...