`

Linux程序调试--内存地址对齐

阅读更多

改编自:

http://blog.csdn.net/donkeylong/archive/2009/12/01/4909720.aspx

一,内存地址对齐的概念

计算机内存中排列、访问数据的一种方式,包含基本数据对齐和结构体数据对齐。

32位系统中,数据总线宽度为32,每次能够读取4字节数据。地址总线为32,最大寻址空间为4GB。但是由于最低位A[0]~A[1]是不用于寻址的,因此只能访问4的倍数的地址空间,但是寻址空间还是2^30*字长=4GB。

因此内存中除了结构体中成员变量之外的基本类型的开始的手地址最低两位都是0。基本类型数据对齐就是数据在内存中的偏移地址必须是一个字的倍数,以提高读取数据时的性能。为了对齐数据,必须在上个数据结束和下个数据开始处插入一些字节,这就是结构体数据对齐。

二,不进行对齐的影响

例如int a的地址是0x00fffff3,则其字节分布在0x00fffff3~0x00fffff6空间内,为了读取这个int,cpu必须对0x00fffff0和0x00fffff4进行两次内存读取,并处理得出的中间结果。两次内存访问将会浪费大量的时间,因为内存访问的速度远小于CPU处理指令的速度。

三,结构体的内存地址对齐

结构体本身必须是4字节对齐的,而其成员变量则处理规则如下。

以下是Microsoft和GNU对x86架构32位系统的结构体成员的默认对齐方式:

char 1字节对齐

short 2字节对齐

int 4字节对齐

float 4字节对齐

double windows是8字节对齐,linux是4字节对齐

当某一个成员后边的成员变量要求的地址对齐较大,则应该填入一些字节。且总的结构体大小为最大对齐的倍数,因此最后可能还要填充一些字符。

因为上述结构体对齐的原因,将结构体成员按照大小递增/递减方式排序,可以减少结构体占用的空间大小。而这样同时使得对整个结构体的存取的效率变高了(占用小,整个的访问次数可以降低)。

另外一个提高效率的方法是把一些占用字节数较少的成员合并到字节数占用大的成员,形成union类型。比如,

struct Merge{

int b;

union{

int a;

char b;

}

}

占用为8字节。初始化需要3次内存读,3次赋值,3次内存写。

struct UnMerge{

int b;

int a;

char b;

}

占用为12字节。初始化需要2次内存读,3次赋值,1次位移,2次内存写。

但是用CPU的操作换取内存的读写可以很大的提高性能。基本上提高的性能比例等于内存访问次数的较少数目和当前访问次数的比例,此处为(6-4)/4=50%。

数组或者结构体数组只要保证首地址对齐,其中元素不要求对齐,因为对于数组,其中任何元素都可以在1~2次内存访问中获取,对于结构体数组,因为结构体内部是按照上述方式填充,则也不需要结构体数组的元素都地址对齐。

对于性能要求较高的情况,比如tcp/ip协议的首部的定义,可以采用位段(bit-fields)的方式来对整数数据按照需要的字段数分配。当然,位段只能对整数进行操作,如果float和int类型数据放在一起用位段方式显然不行,但是通过位移的方法也可以把char类型数据并入float或者double中。位段也需要遵循结构体对齐的方式。

四,用户自定义

使用#pragma pack指令。

分享到:
评论

相关推荐

    嵌入式Linux C编程入门(第2版) PPT

    2.4 嵌入式linux调试器gdb的使用 49 2.4.1 gdb使用实例 50 2.4.2 设置/删除断点 53 2.4.3 数据相关命令 54 2.4.4 调试运行环境相关命令 55 2.4.5 堆栈相关命令 55 2.5 make工程管理器 55 2.5.1...

    易语言程序免安装版下载

    即,新版支持库可被旧版易语言或易程序使用,旧版支持库也可被新版易语言或易程序使用(只是不支持静态编译)。  静态编译后的易语言EXE/DLL之间不能再共享譬如窗口、窗口组件等类似资源,对于已经静态连接到一个...

    Linux程序开发Gtk+ Gnome库

    第18章 程序调试 283 18.1 用gdb调试应用程序 283 18.1.1 为调试程序做准备 283 18.1.2 获得gdb帮助 284 18.1.3 gdb常用命令 284 18.1.4 gdb 应用举例 286 18.2 用xxgdb调试应用程序 289 第五部分 附 录 附录A ...

    Linux应用程序开发指南

    第18章 程序调试 283 18.1 用gdb调试应用程序 283 18.1.1 为调试程序做准备 283 18.1.2 获得gdb帮助 284 18.1.3 gdb常用命令 284 18.1.4 gdb 应用举例 286 18.2 用xxgdb调试应用程序 289 第五部分 附 录 附录A ...

    grub4dos-V0.4.6a-2017-02-04更新

    受内存限制,当前大字库可支持到 32*32,中文小字库可支持到 40*40. 2.不再支持 vga 图形模式。 2015-07-07(yaya) 1.支持每像素16位彩色模式(64K 5:6:5)。 2.支持 jpg(jpeg,jpe)图像格式。 3.在 vbe ...

    Ray4Laz:raylib 3.5到Pascal的完整头转换(绑定)。 没有用于内存对齐问题的任何时髦的辅助函数。 受Fez 3.2.0及更高版本支持,部分基于drezgamesraylib-pascal绑定,但是更简洁,更新

    装订标头支持的raylib.h :check_mark: raymath.h :check_mark: 平台类作业系统支持的苹果 :red_question_mark: 没有测试视窗 :check_mark: Linux :check_mark: 生成和安装raylib 上提供了适用于Windows,Linux和...

    uboott移植实验手册及技术文档

    4、交叉编译器 arm-softfloat-linux-gnu-gcc-3.4.5 【实验步骤】 一、建立自己的平台类型 (1)解压文件 #tar jxvf u-boot-1.3.1.tar.bz2 (2)进入 U-Boot源码目录 #cd u-boot-1.3.1 (3)创建自己的开发板...

    链接器和加载器.PDF(链接器和加载器 Beta 2)

    由于那时内存很贵且容量有限,计算机的速度很慢(以今天的标准),为了创建复杂的内存覆盖策略(以将大容量的程序加载到小容量内存中),以及重新编辑先前链接过的文件(以节省重新创建程序的时间),这些链接器都...

    Reversing:逆向工程揭密

    3.6.3 区段对齐(Section Alignment) 95 3.6.4 动态链接库 96 3.6.5 头部 97 3.6.6 导入与导出 99 3.6.7 目录 99 3.7 输入与输出 103 3.7.1 I/O系统 103 3.7.2 Win32子系统 104 3.8 结构化异常处理 105 3.9 结论 ...

    Python Cookbook

    17.10 调试内存问题 614 第18章 算法 616 引言 616 18.1 消除序列中的重复 619 18.2 在保留序列顺序的前提下消除其中的重复 621 18.3 生成回置采样 625 18.4 生成无回置的抽样 626 18.5 缓存函数的返回值 ...

Global site tag (gtag.js) - Google Analytics