原创 设计 arm 中的 unaligned structure 的 access function(一)

2010-5-11 16:29 3281 8 8 分类: 消费电子

设计 arm 中的 unligned structure access function

 

前言:

arm , structure 的定义与使用, 有很多自相矛盾之处.Allen 尝试将这些矛盾说明如下:

////

(1)    arm access data 永远需要 data aligned.

(2)    为了保证 aligned, 如果我们定义的 structure unaligned, 编译器会自行给strcture 加上 pad bytes, 把我们的 structure 变成 aligned.

(3)    为了不被 compiler pad 工作, 我们需要定义我们的 structure aligned.

(4)    为了避免我们定义 aligned structure 中的小心翼翼甚至是烦人的调整. 编译器允许我们自行定义 align 1. structure 定义成 packed. 这样我们不用对我们的 member, 进行烦人的计算调整和排序.

(5)    为了避免 packed structure , unaligned member access 带来的富余的code, speed的延迟, 以及避免使用指向 unaligned member 时产生的错误, 我们需要进行一种设计. 这种设计是完成一种 access function. 避免编译器原有的令人失望的 access 的模式(为了正确定位加入的富余代码).

////
这些矛盾需要我们, 定义构建这样的 structure, 以 real space 存在于 memory 中. 并仍然保持 code size, access 的 high speed.

 

参考:

ARM C/C++ Compiler Reference Guide, 该文档伴随IAR IDE共同发布. 为简化起见, 我们在之后的讨论中, 将该文档统称为 reference.

 

现象描述:

Default settings , 编译器自行将 structure 的成员变成 aligned 格式:

(1) arm 要求 access data align data. 我们假设 default align 4.

(2) 我们随手定义一个 structure, 只有一个 char 的成员, 它的size 1. 对于这个信手定义的一个 structure, 显然它就不是 align 4 .

default settings, 编译器会自动做 align 的工作. 这就意味着, 编译器自行给这个 struction 足足加了 3 bytes pad bytes. 我们知道, arm 喜欢这样, 对这种 aligned  structure, arm access 既快又准.

(3) 问题是, 我们工程师是否喜欢这种补丁bytes? Reference 列出 engineer 不喜欢被编译器这样做的两个理由:

(a) 网络通讯协议中使用到的一系列的数据类型, 通常是没有任何 padding (Allen 不明白这里意指, 假设这是说, 使用 arm 开发协议转换功能的工程师, 往往会定义一类 structure, 有待直接插入一段 data header or tail, 以实现协议扩展. 而诸多网络协议中, 可没有为什么 pad bytes 预留不确定的定义空间).

(b) 节省 data memory.

不同与以上列举, Allen 这里列出我们的project, 不希望加入这个 pad 的理由. 因为我们需要将 structure 保存在 flash , 作为user可配置参数使用. 对于这样的 structure, 我们期望在 structure 中每一个成员, 都以真实的size在物理空间做真实的排列. 难道这不是最符合逻辑的设计吗?.

 

使用 #pragma pack(1) 强制 align 1.

       编译器给我们这样一个选择, pack(N), N表示我们定义给 structure align. 我们强制定义某个 structure align 1. 那么这时, 编译器便不再给我们的 structure 带来 pad bytes. 但是用这种方式定义的 structure, 每一次对 unaligned 成员进行 access, 都会带来多余的代码. Reference 说这是一种既大又慢的 ways. 那么假设我们的 code , 如果含有这样的 #pragma pack(1) 定义的 structure, 我们便不得不面对这个 problem 带来的庞大低效的problem.

       另外要提醒的是, reference 一个重要的提示, 那就是对于 packed structure之中的 unligned member, 如果仅仅是加上富余的 code 来实现 access 那便还好. 可是如果使用指针去做这样的一个 access. 这个unaligned member 的指针, 将可能不明白应该产生富余代码来做正确的访问, 而采用了更小更快的访问途径(我假设这种途径是针对 aligned member), 这时会产生错误的结果.

       根据我们的工作经验, 这样的行为, 一般都会产生一个编译器警告. 我们遇到过这样的警告(而不是错误), 尽管存在这样的警告, 编译在这种情形下还是被完成了的``` 这更令人担心```

 

 自行完成 function 实现对 packing structure 进行访问.

这是来自 reference 的另一个建议, Allen 可以想象出, 这样的一个函数大致是什么样子, 这个函数应该是, structure 中的首成员的地址, 作为起始参考地址. 并很可能以 #define memberN_offset xxx 的方式, 寻找到需要 access memberN, 再返回 memberN 的指针. 通过这样的方式, 我们访问一个 unligned member 的时候, compiler 就不会为我们加上富余的 code.

 

 重新安排 structure 中的 member aligned

在上述讨论进行后, 看来一个似乎最简单的方式应该是, 我们应规范我们对 structure 的定义, 小心的定义 member, 以及小心调整各个成员的位置, 依次整理每个成员的 size 累加到 4的倍数, 不给编译器插入 pad byte 的机会这样定义后, 我们就不必使用 #pragma pack(1).


设计 arm 中的 unaligned structure 的 access function(一)  

设计 arm 中的 unaligned structure 的 access function(二) 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /3 下一条