c - "double"类型是否需要 8 字节对齐?

标签 c cpu memory-alignment

我理解字对齐,就是让cpu在读一个整数到一个寄存器的时候只需要读一次。

但是是8-byte alignment (让我们假设 32 位系统)“双”有必要吗?有什么好处?如果存储“double”的空间只是4字节对齐会怎样?

最佳答案

有多个硬件组件可能会受到未对齐的加载或存储的不利影响。

  • 内存接口(interface)可能有八个字节宽,并且只能访问八个字节的倍数的内存。然后加载一个未对齐的八字节 double 需要在总线上进行两次读取。存储更糟糕,因为对齐的八字节存储可以简单地将八个字节写入内存,但未对齐的八字节存储必须读取两个八字节的片段,将新数据与旧数据合并,然后写入两个八字节的片段.
  • 缓存行通常为 32 或 64 字节。如果八字节对象对齐到八字节的倍数,那么每个对象只在一个缓存行中。如果它们未对齐,则某些对象部分在一个缓存行中,部分在另一个缓存行中。然后加载或存储这些对象需要使用两个缓存行而不是一个。这种效果发生在所有级别的高速缓存(现代处理器中三级并不少见)。
  • 内存系统页面通常为 512 字节或更多。同样,每个对齐的对象都在一页中,但一些未对齐的对象在多个页面中。访问的每个页面都需要硬件资源:虚拟地址必须转换为物理地址,这可能需要访问转换表,并且必须检测地址冲突。 (处理器可能同时运行多个加载和存储操作。即使您的程序可能看起来是单线程的,处理器也会提前读取指令并尝试执行它可以执行的指令。因此处理器可能会在执行之前启动加载指令指令已经完成。但是,为了确保这不会导致错误,处理器检查每个加载指令以确保它不是从先前存储指令正在更改的地址加载。如果访问跨越页面边界,则两个部分加载数据必须单独检查。)

系统对未对齐操作的响应因系统而异。一些系统被设计为仅支持对齐访问。在这些情况下,未对齐访问要么导致导致程序终止的异常,要么导致执行模拟软件中未对齐操作的特殊处理程序的异常(通过执行对齐操作并在必要时合并数据)。诸如此类的软件处理程序比硬件操作慢得多。

一些系统支持非对齐访问,但这通常比对齐访问消耗更多的硬件资源。在最好的情况下,硬件执行两个操作而不是一个。但是某些硬件被设计为开始操作时就好像它们是对齐的一样,然后在发现操作未对齐时中止它并重新开始使用硬件中的不同路径来处理未对齐的操作。在此类系统中,未对齐访问会显着降低性能,尽管它不如软件处理未对齐访问的系统严重。

在一些系统中,硬件可能有多个加载-存储执行单元,它们可以执行未对齐访问所需的两个操作,就像一个单元可以执行对齐访问操作一样快。所以不存在未对齐访问的直接性能下降。但是,由于未对齐访问使多个执行单元保持忙碌状态,因此它们无法执行其他操作。因此,执行许多加载-存储操作(通常是并行的)的程序在使用未对齐访问时比使用对齐访问时执行得更慢。

关于c - "double"类型是否需要 8 字节对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21219130/

相关文章:

c - pthread_join() 导致崩溃后指向 int 的指针

c - 使用ShellExecute()时是否需要初始化COM?

java - Heroku 中的 CPU/内存监控(适用于 Java)

c - 调查 Valgrind 无效读取

c++ - 为什么结构大小与项目大小的简单总和不匹配?

c - 我在 flex/bison 中的所有 token 都显示为未声明

c - 解释这个汇编代码

非交错存储元组的 C++ 容器

c++ - 定期调用 GetProcessTimes 返回相同的结果

javascript - 游戏循环中 getImageData() 的 Canvas 绘制时间问题