编写可移植代码而值得考虑的最后一个问题是如何存取不对齐的数据 -- 例如, 如何读取 一个存储于一个不是 4 字节倍数的地址的 4 字节值. i386 用户常常存取不对齐数据项, 但是不是所有的体系允许这个. 很多现代的体系产生一个异常, 每次程序试图不对齐数据 传送时; 数据传输由异常处理来处理, 带来很大的性能牺牲. 如果你需要存取不对齐的数 据, 你应当使用下列宏:

#include <asm/unaligned.h> get_unaligned(ptr); put_unaligned(val, ptr);

这些宏是无类型的, 并且用在每个数据项, 不管它是 1 个, 2 个, 4 个, 或者 8 个字节 长. 它们在任何内核版本中定义.

关于对齐的另一个问题是跨平台的数据结构移植性. 同样的数据结构( 在 C-语言 源文件 中定义 )可能在不同的平台上不同地编译. 编译器根据各个平台不同的惯例来安排结构成 员对齐.

为了编写可以跨体系移动的数据使用的数据结构, 你应当一直强制自然的数据项对齐, 加 上对一个特定对齐方式的标准化. 自然对齐意味着存储数据项在是它的大小的整数倍的地 址上(例如, 8-byte 项在 8 的整数倍的地址上). 为强制自然对齐在阻止编译器以不希望 的方式安排成员量的时候, 你应当使用填充者成员来避免在数据结构中留下空洞.

为展示编译器如何强制对齐, dataalign 程序在源码的 misc-progs 目录中发布, 并且一 个对等的 kdataalign 模块是 misc-modules 的一部分. 这是程序在几个平台上的输出以 及模块在 SPARC64 的输出:

249

arch Align:

char

short

int

long

ptr

long-long

u8

u16

u32

u64

i386

1

2

4

4

4

4

1

2

4

4

i686

1

2

4

4

4

4

1

2

4

4

alpha

1

2

4

8

8

8

1

2

4

8

armv4l

1

2

4

4

4

4

1

2

4

4

ia64

1

2

4

8

8

8

1

2

4

8

mips

1

2

4

4

4

8

1

2

4

8

ppc

1

2

4

4

4

8

1

2

4

8

sparc

1

2

4

4

4

8

1

2

4

8

sparc64

1

2

4

4

4

8

1

2

4

8

x86_64

1

2

4

8

8

8

1

2

4

8

kernel: arch Align: char short int long ptr long-long u8 u16 u32 u64
kernel: sparc64     1    2     4   8    8   8         1  2   4   8

有趣的是注意不是所有的平台对齐 64-位值在 64-位边界上, 因此你需要填充者成员来强
制对齐和保证可移植性.

最后, 要知道编译器可能自己悄悄地插入填充到结构中来保证每个成员是对齐的, 为了目 标处理器的良好性能. 如果你定义一个结构打算来匹配一个设备期望的结构, 这个自动的 填充可能妨碍你的企图. 解决这个问题的方法是告诉编译器这个结构必须是"紧凑的", 不 能增加填充者. 例如, 内核头文件
<linux/edd.h> 定义几个与 x86 BIOS 接口的数据结 构, 并且它包含下列的定义:

struct

{

}

u16 id; u64 lun;

u16 reserved1;

u32 reserved2;

attribute   ((packed)) scsi;

如果没有  
attribute   ((packed)), lun 成员可能被在前面添加 2 个填充者字节或者

6 个, 如果我们在 64-位平台上编译这个结构.

Linux数据对齐的更多相关文章

  1. 数据对齐 posix_memalign 函数详解

    对齐 数 据的对齐(alignment)是指数据的地址和由硬件条件决定的内存块大小之间的关系.一个变量的地址是它大小的倍数的时候,这就叫做自然对齐 (naturally aligned).例如,对于一 ...

  2. C++中数据对齐问题。struct、union、enum,类继承。再谈sizeof()

    首先是struct,在C++中,结构体其实和class有很大的相似了.但是有一点不同的是,struct默认是public,而class中是private. 当然,struct继承等用法也是可以的. 共 ...

  3. gcc数据对齐之: howto 2.

    原文链接:http://www.catb.org/esr/structure-packing/ 谁应阅读本文 本文探讨如何通过手工重新打包C结构体声明,来减小内存空间占用.你需要掌握基本的C语言知识, ...

  4. C++中数据对齐

    大体看了看数据对齐,不知道是否正确,总结如下: struct A { char name; double dHeight; int age; }; sizeof(A) = (1+7+8+4+4) =  ...

  5. Linux数据包路由原理、Iptables/netfilter入门学习

    相关学习资料 https://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html http://zh.wik ...

  6. 配置Linux数据转发(给其他接口转发一个接口的internet网络)

    配置Linux数据转发 [主机]第一步开启转发net.ipv4.ip_forward = 1echo "1" > /proc/sys/net/ipv4/ip_forward第 ...

  7. C/C++数据对齐汇总

     C/C++数据对齐汇总  这里用两句话总结数据对齐的原则: (1)对于n字节的元素(n=2,4,8,...),它的首地址能被n整除,才干获得最好的性能: (2)如果len为结构体中长度最长的变量,s ...

  8. gpu显存(全局内存)在使用时数据对齐的问题

    全局存储器,即普通的显存,整个网格中的随意线程都能读写全局存储器的任何位置. 存取延时为400-600 clock cycles  很easy成为性能瓶颈. 訪问显存时,读取和存储必须对齐,宽度为4B ...

  9. 结构体的数据对齐 #pragma浅谈

    之前若是有人拿个结构体或者联合体问我这个结构占用了多少字节的内存,我一定觉得这个人有点low, 直到某某公司的一个实习招聘模拟题的出现,让我不得不重新审视这个问题, 该问题大致如下: typedef ...

随机推荐

  1. pl/sql基础知识—包

    n  包 包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成. 为什么需要包:使用包可以更好的管理自己写的函数.过程 ①我们可以使用create package命令来创建包:     creat ...

  2. jQuery之父:坚持每天都要写代码

    关于作者:John Resig, jQuery之父,同时也是Pro Javascript Techniques和Secrets of the JavaScript Ninja的作者.他目前主持 Kha ...

  3. srand函数

    srand函数是随机数发生器的初始化函数. 原型: void srand(unsigned seed); 用法:它需要提供一个种子,这个种子会对应一个随机数,如果使用相同的种子后面的rand()函数会 ...

  4. 开启远程XUL

    参考:https://developer.mozilla.org/zh-cn/Remote_XUL firefox自4.0起(2011年4月版本,目前最新版为13.0),开始禁用远程XUL,这阻碍了初 ...

  5. 2019-8-31-dotnet-使用-System.CommandLine-写命令行程序

    title author date CreateTime categories dotnet 使用 System.CommandLine 写命令行程序 lindexi 2019-08-31 16:55 ...

  6. aspcms安装所遇到的问题

     aspcms标签:http://biaoqian.iasp.com.cn/ 1.报错:An error occurred on the server when processing the URL. ...

  7. HZOJ 导弹袭击

    比较显然的一个性质是如果存在$a(i)>=a(j) \& \& b(i)>=b(j)$那么j没用. 我们并不需要A,B的具体取值,我们之关心$\frac {A}{B}$. ...

  8. 不撞南墙不回头———深度优先搜索(DFS)Oil Deposits

    Oil Deposits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  9. MyBatis动态批量插入、更新Mysql数据库的通用实现方案

    一.业务背景 由于需要从A数据库提取大量数据同步到B系统,采用了tomikos+jta进行分布式事务管理,先将系统数据源切换到数据提供方,将需要同步的数据查询出来,然后再将系统数据源切换到数据接收方, ...

  10. 13 -1 BOM和定时器

    一 BOM JavaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等. DOM:文档对象模型,操作网页上的元 ...