Data alignment
C语言,在对一个 struct variable使用 sizeof operator(操作符)的时候,往往得到的结果并不是我们想象中——struct内所有member的size之和。
当清楚了什么是Data alignment(数据对齐),对这个问题就豁然开朗了。
Data Alignment
Data Alignment 并非针对 Data 本身,而是Data(Variable)的内存地址 。在 MSDN 对 Alignment做出定义,其第一句话便是
Alignment is a property of a memory address
以一张表格来展现32-bit machine 的内存结构
计算机中,内存是由大量的,连续的,可寻址的或编了号的memory cells(内存单元)构成。每个memory cell 占1 byte。
假如上述表格 bank0的address 为X,那么bank1,bank2,bank2的地址分别为X+1,X+2,X+2。
CPU在处理内存数据时,并非一次提取一个memory cell,一般提取一组相邻内存单元。在32-bit machine,CPU一次从内存中读取 4个连续的memory cell(4-byte) 。所以在此表格中,4 byte chunk(4字节流) 为一个读取周期。在读取一个int型 数据时,仅仅需要一个周期(int 占4 byte)。读取Double型,则需要2个读取周期。表格(D0-D31,32-bit)表示一个内存周期。如果是8-bit machine 即1字长(D0-D7),则需要4个周期来读取一个integer。
说了一些基本的内存知识,接下来看看 MSDN对Alignment的定义是怎么样的
Alignment is a property of a memory address, expressed as the numeric address modulo a power of 2. For example, the address 0x0001103F modulo 4 is 3; that address is said to be aligned to 4n+3, where 4 indicates the chosen power of 2. The alignment of an address depends on the chosen power of two. The same address modulo 8 is 7.
An address is said to be aligned to X if its alignment is Xn+0.
CPUs execute instructions that operate on data stored in memory, and the data are identified by their addresses in memory.
仔细理解下,可以总结为,当向内存中放入一个数据(variable)时,此数据的地址,严格来说是offset,起始地址,必须是此数据的Alignment的整数倍。即上述 Xn+0。
对于每种类型的数据,都有其自身的Alignment
Data Type | Alignments(in Bytes) |
char | 1 |
short | 2 |
int | 4 |
float | 4 |
double | 4 or 8 |
例如char 的offset可以在bank0,bank1,bank2,bank3任意一个(这里为了方便,假设bank0初始位置的address为0,依次类推)。short型的2 bytes只能存储在 bank0-bank1或者bank2-bank3,假如其offset在bank1上,即存储在bank1-bank2,那么此address为奇数,并非short alinment的整数倍。
int型,offset只能在bank0上,在其他位置,都不会是4的整数倍。如果一个int型的整数,0xABCDEF,在内存中的起始位置在 bank1 上会发生什么呢?
可以看到此integer的addres并非是4的整数倍,跨过两行,那么在读取此data时,就需要两个读取周期了。
所以 data alignment正是用来处理variable在这些bank中的存储方式。 以避免发生此情况。在上表中,此整数的地址为5,5=4n+1,按照MSDN定义来说,此整数的alignment为1.但是int 型的alignment应该是4。所以这种情况又称为 misaligned 。
Data Structure Padding
在C/C++中,因为对variable都有alignment的要求,所以在struct中,每一个member都要遵循alignment的要求。就拿 MSDN中的一个例子,来谈下struct的alignment
- struct x_
- {
- char a; // 1 byte
- int b; // 4 bytes
- short c; // 2 bytes
- char d; // 1 byte
- } MyStruct;
同上述表格一样,struct中的member在内存中,是由下至上allocate的。
char a的起始位置在bank0,假如addrees为0;
int b,是不可以在bank1,bank2,bank3,这样b的offset为奇数,不是4的整数倍,所以只能在bank4,其4 bytes在 bank4-bank5-bank6-bank7;
那么在char a与int b之间需要填补3个无意义的byte。来满足int b的对齐方式。
short c是可以在bank8的,8为2的整数倍。所以b,c间无需要填补。那么short c 存储在 bank8-bank9。
char d可以存储在任何位置。那么char d 则存储在 byte10.
最后需填补1 byte
padding byte | char d | short c | short c |
int b | int b | int b | int b |
padding byte | padding byte | padding byte | char a |
在最后填补一个byte的原因是:
在struct的member的alignment中,找到alignment的最大值(此处为4 bytes),在struct的最后一个member填补 padding bytes使整个struct的size 为此aligment(4 bytes)的整数倍。
所以上述struct 在内存中的实际形式为
- // Shows the actual memory layout
- struct x_
- {
- char a; // 1 byte
- char _pad0[3]; // padding to put 'b' on 4-byte boundary
- int b; // 4 bytes
- short c; // 2 bytes
- char d; // 1 byte
- char _pad1[1]; // padding to make sizeof(x_) multiple of 4
- }
此struct的size为12 bytes,而不是8 bytes。
Resource
http://msdn.microsoft.com/en-us/library/ms253949.aspx
http://en.m.wikipedia.org/wiki/Data_structure_alignment#section_5
http://www.geeksforgeeks.org/archives/9705
http://www.songho.ca/misc/alignment/dataalign.html
Data alignment相关推荐
- 为什么要内存对齐 Data alignment: Straighten up and fly right
为了速度和正确性,请对齐你的数据. 概述:对于所有直接操作内存的程序员来说,数据对齐都是很重要的问题.数据对齐对你的程序的表现甚至能否正常运行都会产生影响.就像本文章阐述的一样,理解了对齐的本质还能够 ...
- DPDK(Data Plane Development Kit)快速处理数据包 开发平台及接口 简介
一.网络IO的处境和趋势 从我们用户的使用就可以感受到网速一直在提升,而网络技术的发展也从1GE/10GE/25GE/40GE/100GE的演变,从中可以得出单机的网络IO能力必须跟上时代的发展. 1 ...
- Data Types in the Kernel [LDD3 11]
为什么要单独讲kernel的数据结构? kernel是一个支持很多平台很多架构的OS,不同的架构上,很多的数据结构都是不同的,如何保证kernel能兼容多个架构,这就得益于kernel良好的数据结构设 ...
- Hi-C data analysis tools and papers
Hi-C data analysis tools and papers 全文链接如下: https://github.com/mdozmorov/HiC_tools Tools are sorted ...
- 【嵌入式烧录/刷写文件】-1.9-S19文件的地址对齐Address Alignment
案例背景(共5页精讲): 对一个Motorola S-record(S19/SREC/mot/SX)文件,进行地址对齐Address Alignment. 目录 1 为什么要进行"地址对齐A ...
- 计算机视觉系列最新论文(附简介)
计算机视觉系列最新论文(附简介) 目标检测 1. 综述:深度域适应目标检测标题:Deep Domain Adaptive Object Detection: a Survey作者:Wanyi Li, ...
- pandas学习之Series结构
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 系列(值的集合) DataFrame数据包(系列对象的集合) panel ...
- PostgreSQL 9.3 beta2 stream replication primary standby switchover bug?
[更新] 已有patch. 请参见. PostgreSQL 9.1,9.2,9.3 clean switchover Primary and Standby Patch. http://blog.16 ...
- 【pandas学习笔记】综合整理
1. Reindex Series Reindex import numpy as np import pandas as pd >>>s1 = pd.Series(np.rando ...
最新文章
- CVPR 2018 | ETH Zurich提出利用对抗策略,解决目标检测的域适配问题
- Angular 默认的Change detection策略及缺陷
- 手把手带你玩转Tensorflow 物体检测 API (3)——训练模型
- Oracle创建表空间及用户
- python之django中models学习总结
- Linux创建文本文件【Ubuntu】
- 学习笔记(12):Google开发专家带你学 AI:入门到实战(Keras/Tensorflow)(附源码)-深度学习“四件套”:数据、模型、损失函数与优化器
- java线程栈日志_Java线程堆栈
- dns外带数据【渗透测试】
- 【iOS】Plist-XML-JSON数据解析
- 认识一下,JavaScript今年25岁啦
- 初识js-charts和E-charts
- oracle grant all语句,Oracle 生成批量 Grant 语句的 SQL
- 简单计算器(C 语言实现)
- 什么叫做专用的IP地址?
- 学车笔记 -- 侧方位(一字型)停车
- 51单片机用c语言在液晶1602上显示汉字,lcd1602与单片机连接图,基于51单片机的lcd1602液晶显示屏连接电路图...
- Linux下查看电脑硬件配置
- CSCW领域的“老”词和“新”词
- 打开网络显示连接的服务器在哪里找,电视网络与服务器连接设置在哪里找
热门文章
- Android Studio 佛祖保佑 永无bug 注释模板设置详解(仅供娱乐)
- Opencv的Vec类使用说明(图像像素.at方法访问)
- c语言实型数据的运算-分期付款
- 小沙的长路 【欧拉图】
- 金山网络-度过生死线
- oracle教程新w3c,Oracle技术教程
- 回收站删除的文件能恢复吗?回收站文件恢复,3招解决
- uniapp 微信小程序 - 调起手机摄像头: 拍摄身份证的正反面,自定义身份证取景框,在相机上绘制 “身份证轮廓“ 与提示文字(超详细示例源码,一键复制运行开箱即用)
- 开源php ugc 社区,如何设计UGC社区的内容展示规则?
- 全世界游客访问最多的城市,重庆以5.9亿游客量排名第一