laa*_*lto 20
它肯定会在某些系统上引起问题.
例如,在基于ARM的系统上,您无法寻址未与4字节边界对齐的32位字.这样做会导致访问冲突异常.在x86上,您可以访问这些非对齐数据,但性能会受到一点影响,因为必须从内存中取出两个单词而不是一个单词.
Tam*_*ege 13
以下是英特尔x86/x64参考手册中有关对齐的内容:
4.1.1单词,双字,四字和双四字的对齐
单词,双字和四字不需要在自然边界的内存中对齐.单词,双字和四字的自然边界是偶数地址,地址可被4整除,地址可分别被8整除.但是,为了提高程序的性能,数据结构(尤其是堆栈)应尽可能在自然边界上对齐.原因是处理器需要两次存储器访问才能进行未对齐的存储器访问; 对齐访问只需要一次内存访问.跨越4字节边界的字或双字操作数或跨越8字节边界的四字操作数被认为是未对齐的,并且需要两个单独的存储器总线周期来进行访问.
一些操作双四字的指令要求存储器操作数在自然边界上对齐.如果指定了未对齐的操作数,则这些指令会生成一般保护异常(#GP).双四字的自然边界是可被16整除的任何地址.对双四字运算的其他指令允许未对齐访问(不产生一般保护异常).但是,从存储器访问未对齐的数据需要额外的存储器总线周期.
不要忘了,参考手册是负责开发者和工程师的信息的最终来源,因此,如果您正在处理的事情有据可查,如英特尔CPU,只看了一下参考手册中说,有关的问题.
是的,这可能会导致许多问题。C++ 标准实际上并不能保证它能够工作。您不能在指针类型之间任意转换。
当您将 char 指针转换为双指针时,它使用 a reinterpret_cast,它应用实现定义的映射。您不能保证生成的指针将包含相同的位模式,或者它将指向相同的地址或其他任何内容。从更实际的角度来说,您也不能保证您正在读取的值正确对齐。如果数据被写入一系列字符,那么它们将使用字符的对齐要求。
至于对齐的含义,本质上就是值的起始地址应该能被对齐大小整除。例如,地址 16 在 1、2、4、8 和 16 字节边界上对齐,因此在典型的 CPU 上,这些大小的值可以存储在那里。
地址 6 未在 4 字节边界上对齐,因此我们不应该在那里存储 4 字节值。
值得注意的是,即使在不强制或不需要对齐的 CPU 上,访问未对齐的值通常也会显着减慢速度。
| 归档时间: |
|
| 查看次数: |
21449 次 |
| 最近记录: |