数据对齐 总结
来源:互联网 发布:vm mac共享文件夹 编辑:程序博客网 时间:2024/06/15 06:56
Author: Yang Honggang (Joseph) <eagle.rtlinux@gmail.com>
Content: Data alignment
Date: 12-08-2011
REF:
1> Computer Systems A Programmer's Perspective (version 2)
3.9.3 Data Alignment
2> Linux Device Driver 3
11.4.4. Data Alignment
=============================================================
Many computer systems place restriction on the allowable addresses for the
primitive data types, requiring that the address for some type of object
must be a multiple of some value K( 2, 4 or 8). Such alignment restrictions
simplify the design of the hardware forming the interface between the processor
and the memory system.
For example, suppose a processor always fetches 8 bytes from memory with an
address that must be a multiple of 8, then the value can be read or written
with a single memory operation. Otherwise, we may need to perform two
memory accesses, since the object might be split across two 8-byte memory blocks.
Linux follows an alignment policy where 2-byte data types (e.g., short) must
have an address that is a multiple of 2, while any larger data types (e.g.,
int, int*, float, and double) must have an address that is a multiple of 4.
Any objcet of type int, or any pointer, must be at an address having the
low-order 2 bits equal to zero.
NOTE:
Some of SSE instructions for implementing multimedia operations will
not work correctly with unaligned data. These instructions operate on
16-byte blocks of data, and the instructions that transfer data between
the SSE unit and memory require the memory addresses to be multiples of
16, or it will lead to an exception, with the default behavior for the
program to terminate.
This is the motivation behind the IA32 convetion of making sure that every
stack frame is a multiple of 16 bytes long. The compiler can allocate
storage within a stack frame in such a way that a block can be stored with
a 16-byte alignment.
Liray routines that allocate memory, such as malloc, must be designed so that
they return a pointer that satisfies the worse-case alignment restriction for
the machine it is running on, typically 4 or 8.
As the structures, compiler inserts byte gaps [1], or padd to its end [2] to satisfy
the alignment requirement for every fields.
The following program 'data_align.c' gives a good example.
--------------------------------------------------
Finally, as the compiler may quietly insert padding into structures itself to ensure
that every field is aligned for good performance on the target processor. If you are
defining a structure that is intended to match a structure expected by a device, this
automatic padding may thwart your attempt. The way around this problem is to tell the
compiler that the structure must be "packed," with no fillers added. For example, the
kernel header file <linux/edd.h> defines several data structures used in interfacing
with the x86 BIOS, and it includes the following definition:
struct {
u16 id;
u64 lun;
u16 reserved1;
u32 reserved2;
} __attribute__ ((packed)) scsi;
Without the _ _attribute_ _ ((packed)), the lun field would be preceded by two filler
bytes or six if we compile the structure on a 64-bit platform.
This is also showed in our example 'data_align.c'.
#include <stdio.h>struct S1 {int i;char c;int j;};struct S2 {int i;int j;char c;};struct All { struct S1 s1;int a;struct S2 s2;};struct SS1 {int i;char c;int j;} __attribute__ ((packed)) ss1;int main(void){char a_char;int a_int;float a_float;double a_double;int* p; struct SS1 ss2;struct S1 s1;struct S2 s2;struct All a; printf("Force compiler not to leave the structure what it is\n");printf("sizeof(ss1) is %d\n", sizeof(ss1)); printf("sizeof(ss2) is %d\n", sizeof(ss2));printf("------------------------"); printf (" struct All {\n"" struct S1 s1;\n"" int a;\n"" struct S2 s2;\n"); printf("&a %p\n" "&a.s1 %p\n" "&a.a%p\n" "&a.s2%p\n", &a, &a.s1, &a.a, &a.s2 );printf("sizeof(a) %d\n", sizeof(a));printf("----\a\a\a\a\a\a\a\a\a\a--------------\n"); printf("struct S1 {\n"" int i;\n"" char c;\n"" int j;\n" " };\n");printf("&s1 %p\n" "&s1.i %p\n" "&s1.c%p\n" "&s1.j%p\n", &s1, &s1.i, &s1.c, &s1.j);printf("sizeof(s1) %d\n", sizeof(s1)); printf("---------------------\n"); printf("struct S2 {\n"" int i;\n"" int j;\n"" char c;\n" " };\n");printf("&s2 %p\n" "&s2.i %p\n" "&s2.c%p\n" "&s2.j%p\n", &s2, &s2.i, &s2.c, &s2.j);printf("sizeof(s2) %d\n", sizeof(s2)); printf("---------------\n");printf("sizeof: char %d\n""int %d\n""float%d\n""double%d\n""pointer %d\n", sizeof(char),sizeof(int),sizeof(float),sizeof(double),sizeof(p));printf("&a_char %p\n&a_int %p\n&a_float %p\n""&a_double %p\n&p %p\n", &a_char, &a_int, &a_float, &a_double, &p);return 0;}
Example 2: use standard int types
#include <stdio.h>#include <stdint.h>struct package {uint8_t u_int_8;uint64_t u_int_64;uint32_t u_int_32;uint16_t u_int_16;} a;struct pack {uint8_t u_int_8;uint64_t u_int_64;uint32_t u_int_32;uint16_t u_int_16;} __attribute__ ((packed)) A;int main(void){printf("&a%p\n" "&a.u_int_8%p\n" "&a.u_int_64%p\n" "&a.u_int_32%p\n" "&a.u_int_16%p\n", &a, &a.u_int_8, &a.u_int_64, &a.u_int_32, &a.u_int_16); printf("sizeof(a) is %d\n", sizeof(a)); printf("/1/7------/8+++++++/4+++/2+/2-/\n"); printf("\n--------do not do the data aliged operation -----------\n"); printf("&A%p\n" "&A.u_int_8%p\n" "&A.u_int_64%p\n" "&A.u_int_32%p\n" "&A.u_int_16%p\n", &A, &A.u_int_8, &A.u_int_64, &A.u_int_32, &A.u_int_16); printf("sizeof(A) is %d\n", sizeof(A)); return 0;}result:&a0x600ab0&a.u_int_80x600ab0&a.u_int_640x600ab8&a.u_int_320x600ac0&a.u_int_160x600ac4sizeof(a) is 24/1/7------/8+++++++/4+++/2+/2-/--------do not do the data aliged operation -----------&A0x600aa0&A.u_int_80x600aa0&A.u_int_640x600aa1&A.u_int_320x600aa9&A.u_int_160x600aadsizeof(A) is 15
- 数据对齐 总结
- C/C++数据对齐总结
- 数据对齐 字节对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 数据对齐
- 关于ARM9协处理器CP15及MCR和MRC指令
- php长文章分页问题
- linux下编程用到的autotools工具 生成makefile文件
- linux目录介绍 归档 管道符的管理和应用
- VS2005发布网站问题及"aspnet_merge.exe”已退出,代码为 1的错误
- 数据对齐 总结
- 在同一台机器上运行多个MySQL服务器
- 只能用于构造函数的explicit
- linux命令大全
- a link 标签的disabled属性实现disabled/enable
- MD5加密解密
- VC/MFC之ListCtrl控件使用经验总结
- strace中文
- 通用比较器和类的可比较性