Re: [问题] 8-bit系统还是要data alignment吗?

楼主: tinlans ( )   2016-02-24 00:09:56
※ 引述《anoymouse (没有暱称)》之铭言:
: 标题: [问题] 8-bit系统还是要data alignment吗?
: 时间: Mon Feb 22 22:36:04 2016
:
: 如提
:
: 在读data alignment 碰到一些问题
:
: 1.如果每次都是1 byte抓资料,那就不会有misaligned了问题吧?
: 还是说不管什么系统都要照资料大小的倍数来排内存位址? 感觉8bit没必要啊
讲“系统”还是太笼统了一点。
这东西必须翻阅你平台的 ISA (Instruction Set Architecture) 文件,
看看里面有没有支援大于 8-bit 的运算指令 (如果有的话大概也是多周期的)。
如果有的话,一般也能在 Programming Guide 里看到一些提示跟范例。
另外,如果有 CPU 以外的周边装置,有时是周边装置有不同的 alignment 要求。
这种时候,在内存摆资料当然就是照周边装置的需求去摆。
:
: 2.
: http://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packi
: ng/(缩网好像不能用 抱歉)
: 这网站很下面讲的General Questions 第二点
: 请问是什么意思? 如果是32位元系统不是一律抓32bit吗 不管放在哪一条bank有差吗?
其实这问题问得不好,他想讲的只是一个 char 被放在 4 bytes 里的哪个 byte 罢了。
如果硬件设计上就是只能呆板地一次读 4 bytes,那就是如他所说,
若不是被放在最右边的 byte (即 bank 0),那硬件读 4 bytes 以后会用 shift 处理。
: 这时候又想问 多抓的24bits怎么办? 再摆回去?
丢掉就好了,又没用到。
: 3.Pointer Mishaps 不过似乎没有很详细 只是说pointer有可能会有
: misaligned 主要是下一段说malloc
很简单啊,因为你不知道 void * 这指标是不是指在 4-byte 边界上。
万一不是,你想从这里读一个 int 出来,读内存的指令收到的位址就是 misaligned。
如果这个 CPU 没有提供 unaligned load 指令,那就会发 exception 出来。
一般来说会有人实作好 exception handler 处理掉这问题,方法就是上面讲的读两次。
如果指令支援,你可能会期望 compiler 选用 unaligned load 指令。
但这个是看 compiler 实作决定,而 compiler 如果觉得 unaligned load 比较贵,
那么 compiler 也可能一律采用普通的 load 指令去处理 dereference void * 的状况。
毕竟 malloc () 传回 void *,实作上又往往会保证 malloc () 传回的位址是 aligned,
那么如果 unaligned load 指令所需的 cycle 数较多,compiler 可能就不会选用它。
这些部分是看实作决定,所以一样要读你平台的 Programming Guide 才能知道。
一般低阶的 CPU 没什么特殊设计的话,unaligned load 也是靠 multi-cycle 完成。
有切 pipeline 的 CPU 可能在 decode 完后拆成三个 micro operations,
分别是做两次 load 还有一次调整合并的动作,能 forward 结果的 stage 较晚。
高阶一点 CPU 的 data bus 可能为了一些考量做成 64-bit,
然后因为本来一些乘法和乘加指令就会写入两个 registers (有两个 write ports),
所以 unaligned load 指令可以一口气从内存读出两个 32-bit 资料。
不过合并的部分通常因为高阶 CPU 的 clock rate 高导致 timing 来不及,
还是需要多一个 cycle 才能把两笔 data 调整并合并好。
这些特性都会导致 unaligned load 指令的成本较高,compiler 不喜欢选用,
除非 compiler 完全确定这次 load 是 unaligned,不然还是会倾向使用一般 load。
: "It is usually aligned to 8 byte boundary on 32 bit machines."
: 回传的地址是32bit怎么会是8byte? 求解!
你是不是忘了前面你才刚读过 structc_tag 里跟 double 有关的内文?
:
:
: 谢谢
:
:
: 目前从网页所学习到的是: 网页上所表示的bank的内存位址从0开始,似乎是
: offset的量,但是为了方便计算,所以假装是内存的位址。
:
:
: 我的理解是 以他所举例,32bit系统,bank所配置的来说都是一次抓4bytes,所以bank
: 是从bank0~bank3
: 放满就换下一列,因为一次抓4bytes的关系,又是从0开始找吧,所以每4,4,4,4......
: 的找就得符合资料型别倍数的原则。如果int的资料从bank2开始放,那在抓的时候只会
: 抓到一半,还要在一个工作周期才会抓到下一半。
:
: 虽然short"貌似"从bank1开始放好像没问题,不过根据系统的一致性是最容易设计的
: 原则,让所有的type都符合倍数的内存配置,只好让short只能放在2的倍数的记忆
: 体位址这是我猜的)
如果 CPU 提供 half-word 的 load 指令,也就是 2-byte 的 load 指令,
那么一般预期的是资料要放在 2-byte boundary 上,否则可能发生 exception。
所以 short 放在 bank 0 或 bank 2 才是比较好的。
但是我实在不太喜欢他用 bank 几来讲这观念,习惯上是说对齐 2-byte 边界。
另外,上面讲的 exception 只是可能会被丢出来,不代表所有平台都这样做。
你的 ISA 文件或 Programming Guide 应该要告诉你会发生什么,
因为也可能就真的是只读一半就不读下去了,叫你后果自负。
: 而padding是因为struct里面有各种资料型别,如果建一个结构阵列,结构跟结构之间
: 内部的变量位址都得data alignment,以免下一个结构的资料misaligned。
这同时也告诉你为什么习惯上 malloc () 传回的位址会对齐 8-byte 边界,
因为你可能写 malloc(sizeof(double) * 10) 来做一个 double 动态阵列。
: 所以作者开头提到的四个struct就还看得懂。
作者: cobrasgo (人鱼线变成鲔鱼线,超帅)   2016-02-24 08:36:00
佛心来的…
作者: anoymouse (没有暱称)   2016-02-24 20:01:00
我想一想 谢谢
作者: lc85301 (pomelocandy)   2016-02-24 21:47:00
神人出没不推不行
作者: anoymouse (没有暱称)   2016-02-24 23:15:00
char不是放在最右边那个问题 一次读4byte不是一定会中?如果不是LDRB指令 一般的load指令还需要位移?如果要读AVR的相关ISA 肯定是一段漫长的路啊
作者: damody (天亮damody)   2016-02-25 00:03:00
感谢解释

Links booklink

Contact Us: admin [ a t ] ucptt.com