内存对齐的目的

2023-11-29

不可否认,我不明白。假设您有一个内存,其内存字长度为 1 字节。为什么不能在未对齐地址(即不能被 4 整除)上的单次内存访问中访问 4 字节长的变量,就像对齐地址的情况一样?


现代处理器上的内存子系统仅限于以其字大小的粒度和对齐方式访问内存;造成这种情况的原因有很多。

Speed

现代处理器具有多级高速缓存,数据必须通过这些高速缓存进行提取;支持单字节读取将使内存子系统吞吐量与执行单元吞吐量紧密绑定(也称为 CPU 绑定);这一切都让人想起如何PIO模式被DMA超越出于许多与硬盘驱动器相同的原因。

The CPU always以其字大小读取(32 位处理器上为 4 字节),因此当您在支持它的处理器上进行未对齐地址访问时,处理器将读取多个字。 CPU 将读取您请求的地址跨越的每个内存字。这会导致访问所请求数据所需的内存事务数量最多放大 2 倍。

因此,读取两个字节很容易比读取四个字节慢。例如,假设内存中有一个如下所示的结构:

struct mystruct {
    char c;  // one byte
    int i;   // four bytes
    short s; // two bytes
}

在 32 位处理器上,它很可能会如下所示进行对齐:

Struct Layout

处理器可以在一个事务中读取这些成员中的每一个。

假设您有该结构的打包版本,可能来自为了传输效率而打包的网络;它可能看起来像这样:

Packed Struct

读取第一个字节将是相同的。

当你要求处理器给你 0x0005 中的 16 位时,它必须从 0x0004 中读取一个字并左移 1 个字节以将其放入 16 位寄存器中;一些额外的工作,但大多数都可以在一个周期内完成。

当您从 0x0001 开始请求 32 位时,您将获得 2 倍的放大。处理器将从 0x0000 读入结果寄存器并左移 1 个字节,然后再次从 0x0004 读入临时寄存器,右移 3 个字节,然后OR它与结果寄存器。

Range

对于任何给定的地址空间,如果架构可以假设 2 个 LSB 始终为 0(例如,32 位机器),那么它可以访问 4 倍以上的内存(2 个保存的位可以代表 4 个不同的状态),或者相同的数量具有 2 位的内存用于诸如标志之类的东西。从地址中取出 2 个 LSB 将得到 4 字节对齐;也称为stride4 字节。每次地址递增时,它实际上是递增位 2,而不是位 0,即,最后 2 位将始终继续是00.

这甚至会影响系统的物理设计。如果地址总线需要减少 2 个位,则 CPU 上的引脚可以减少 2 个,电路板上的走线也可以减少 2 个。

原子性

CPU 可以原子地对内存的对齐字进行操作,这意味着没有其他指令可以中断该操作。这对于许多设备的正确操作至关重要无锁数据结构和别的并发性范式。

结论

处理器的内存系统比此处描述的要复杂得多,也更复杂;讨论x86 处理器实际上如何寻址内存可以提供帮助(许多处理器的工作原理类似)。

坚持内存对齐还有更多好处,您可以阅读:这篇 IBM 文章.

计算机的主要用途是转换数据。现代内存架构和技术经过数十年的优化,有助于以高度可靠的方式在更多、更快的执行单元之间输入、输出更多数据。

奖励:缓存

我之前提到的另一个性能对齐是缓存行(例如,在某些 CPU 上)64B 的对齐。

有关利用缓存可以获得多少性能的更多信息,请查看处理器缓存效果图库;由此关于缓存行大小的问题

了解缓存行对于某些类型的程序优化非常重要。例如,数据的对齐可以确定操作是否触及一个或两个高速缓存行。正如我们在上面的示例中看到的,这很容易意味着在未对齐的情况下,操作速度会慢两倍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内存对齐的目的 的相关文章

  • 联合体的大小比预期大。这里如何进行类型对齐?

    include
  • 是否有 java.lang.String 的内存高效替代品?

    看完之后这篇旧文章 http www javaworld com javaworld javatips jw javatip130 html page 2测量几种对象类型的内存消耗 我惊讶地发现有多少内存String在Java中的使用 le
  • IBOutlet、实例变量和属性:最佳实践

    今天 我对有关声明 IBOutlet 和实例变量 管理它们 使用正确的访问器以及正确释放它们的最佳实践进行了各种研究 我已经差不多了 但我有一些小问题 我希望有人能够就最佳实践提出建议 我会将它们格式化为代码并注释问题 以便更容易理解 我排
  • 字符串与 char[]

    我有一些来自 IBM 的幻灯片 名为 从 Java 代码到 Java 堆 了解应用程序的内存使用情况 http www ibm com developerworks library j codetoheap N101DC 也就是说 当我们使
  • 使用放置新运算符时我真的需要担心对齐吗?

    我读了这个我什么时候应该担心对齐问题 https stackoverflow com questions 6474316 when should i worry about alignment但我仍然不知道是否需要担心放置新运算符返回的未对
  • C - 为什么我无法映射较小(256UL 或更小)的内存?

    请告诉我 为什么我的简单应用程序无法映射较小的内存 而且 为什么有这样一个特定的边界 257UL define MAP SIZE 256UL or below fail define MAP SIZE 257UL ok include
  • 已删除的类实例上的方法仍然有效吗?

    我在 Visual C 2010 上有这段代码 include
  • Java 中内存高效的稀疏数组

    关于时间高效的稀疏数组存在一些问题 但我正在寻找内存效率 我需要相当于List
  • 如何计算汇编中的内存位移?

    我一直在研究 yasm 汇编语言 并生成了一个包含以下内容的列表文件 我需要帮助理解第一列中的内存位移是如何计算的 提前致谢 1 line 1 1 memory asm 2 section data 3 00000000 04000000
  • 了解 Linux oom-killer 日志

    我的应用程序被 oom killer 杀死了 它是在实时 USB 上运行的 Ubuntu 11 10 无需交换 PC 具有 1 Gig 的 RAM 唯一运行的应用程序 除了所有内置的 Ubuntu 东西 是我的程序 flasherav 请注
  • 在 python 中 pickling 数据时出现内存错误

    我正在尝试使用 python 中提供的 dump 命令将字典转储为 pickle 格式 字典的文件大小约为 150 mb 但仅转储 115 mb 的文件时会出现异常 例外情况是 Traceback most recent call last
  • MemoryStream“内存不足”C#

    我有一个自定义数据对象 虚拟文件 的实现see here https stackoverflow com questions 4024657 how to drop a file from windows formlistview to d
  • 将数组复制到动态分配的内存

    我的代码可以正常工作 但我觉得好像有一种更快的方法可以做到这一点 特别是在我的函数副本中 这是我的代码 这能再快一点吗 顺便说一句 这是 C 语言 另外 当我从函数返回 cpy 时 它是否会删除动态内存 因为它超出了范围 我不想发生内存泄漏
  • 在问题内显示内联块文本

    我一直在尝试显示内联块 如果我没有在 div 中添加任何内容 一切都会很好 但是当我这样做时 div 会折叠起来 我不知道确切的原因 任何想法 https jsfiddle net giancorzo ebqoptbd https jsfi
  • 在 macOS 中通过 Python 访问进程的压缩 RAM(顶部的 CMPRS)的方法?

    我试图弄清楚如何从 Python 访问任何给定进程占用的实际 RAM 量 我发现 psutil Process PID memory info rss 工作得很好 直到操作系统决定开始压缩某些进程的 RAM 然后 所有的 memory in
  • 虚拟内存澄清——大连续内存的分配

    我有一个应用程序 我必须在 Windows 上分配 使用运算符 new 相当大的内存空间 数百 MB 该应用程序是 32 位 我们现在不使用 64 位 即使在 64 位系统上也是如此 我启用了 LARGEADDRESSAWARE 链接器选项
  • 页面不会居中对齐

    我遇到了 CSS 问题 http www luukratief design nl dump parallax index html http www luukratief design nl dump parallax index htm
  • .net dropdownlist对齐文本

    我正在尝试将 net 下拉列表中的文本向右对齐 使用 CssClass 我可以在 Firefox 中将文本向右对齐 IE 不会将文本右对齐 而是左对齐 我读到 IE 6 不支持这个 这是真的 我使用的是 IE7 但我的大多数用户将使用 IE
  • 编译器特定的内存初始化

    有没有办法保证整个程序中某些对象的静态对象初始化顺序 我有内存分配器 我希望将其作为程序中的第一件事进行分配 因为它们将在整个程序的其他地方使用 并且我想使用这些分配器来分配所有后续内存 我知道这可能是特定于编译器的 因为我不相信 C 标准
  • 在C语言中如何对齐这样的数字?

    我需要将 C 中的一系列数字与printf 就像这个例子 1 5 50 100 1000 当然 所有这些之间都有数字 但这与当前的问题无关 哦 将破折号视为空格 我使用破折号 这样更容易理解我想要的内容 我只能这样做 1 5 50 100

随机推荐

  • Facebook Graph Api url 评论和分享计数不再起作用

    我在我的博客中使用 facebook 评论插件 到目前为止 facebook graph api 帮助我检索我网站上每个帖子的评论计数 因此 正如我所说 我一个月前写的帖子 我可以使用 php 和 json decode 检索评论计数 如下
  • 在另一个 div 内水平和垂直居中 div

    我有一个关于将元素在另一个 div 内水平和垂直居中的问题 我正在为客户开发一个网站 这是给我带来麻烦的页面 http staging slackrmedia com halfpast brand collection bremont ht
  • 使用 store sencha touch 2 将数据加载到列表中

    我已经使用 Sencha touch 2 创建了导航视图 导航视图有列表组件 我想使用商店和模型加载它 我根据需要创建了模型并存储 运行我的应用程序时 列表不会呈现任何数据 它还在 conolse 中发出警告 Ext dataview Li
  • 更改可可中标题栏的颜色

    这个问题肯定有人问过 但谷歌搜索后我仍然找不到答案 如何将标题栏 可以使用关闭 最小化和最大化按钮单击并拖动的标题栏 的颜色更改为与 Cocoa 中默认灰色不同的颜色 如果您设置 纹理 窗口的背景颜色 这一区别在 Snow Leopard
  • For 循环:如何解释更改 ArrayList 大小?

    当 for 循环由 ArrayList 的大小控制时 i lt someArrayList size 但是循环的每次迭代都会向列表中添加一个元素 那么循环如何识别大小正在变化 我认为一旦代码被发送到编译器 它就会看到一次大小 然后执行直到达
  • Android 中两个视图可以同时获得焦点吗

    我有一个 EditText 和一个 popupWindown 其中有一个 ListView 现在我触摸 EditText 弹出窗口显示 我需要这种情况 我可以在 SoftInput 中输入一些内容 并且我还可以单击 ListView 中的子
  • 如何以两种不同的方式为后缀 a++ 和前缀 ++a 重载运算符 ++? [复制]

    这个问题在这里已经有答案了 如何以两种不同的方式为后缀重载运算符 a 和前缀 a 应该看起来像这样 class Number public Number operator prefix Do work on this increment y
  • Django Rest框架自定义Response中间件

    我将 Django Rest Framework 与 rest auth 一起使用 login logout register 我有一个中间件 通常由 user logged in 或 user logged out 信号触发 在我的中间件
  • Rails 中的 find_by_sql,访问结果数组

    我试图在 Rails 中以非常快速和肮脏的方式运行查询 而不将模型的其余部分放在适当的位置 我知道这是不好的做法 但我只需要在紧迫的时间内快速得到结果 直到我找到整个解决方案 我的商品有基于重量的运费 重量存储在商品中 价格存储在表ship
  • 运行可执行文件,然后等待该特定 exe 文件不再运行

    我想运行一个 AHK 可执行文件 然后让 java 等待该可执行文件在其脚本末尾终止它自己的进程 然后继续 是否有一个函数可以监视特定 exe 是否正在运行 如果它正在运行 直到它停止 例如在 AHK 你可以这样做 IfExist Appn
  • 如何使 元素展开或收缩到其父容器?

    目标是拥有
  • 模拟java开发的高CPU负载

    我正在开发一个 Java 应用程序 想看看它如何在较慢 超载的机器上运行 我怀疑可能存在一些线程不安全问题等被忽略 因为我的机器编译得足够快 有没有办法模拟 Java 应用程序的高 CPU 负载 限制可用 CPU 当然 我可以编写一个脚本来
  • C 全局匿名结构/联合

    我有一个 uint64 变量 通常只需要高位或低位 32 位访问 我正在使用 32 位 ARM Cortex M0 为了提高速度 我尝试将 uint64 变量与 C 中的两个 uint32 变量重叠 使用匿名结构 希望避免指针运算来访问成员
  • 如何调整 bash 函数以便省略双引号?

    一整天 我经常输入这样的内容 git stash push u m some phrase as a message 我更愿意输入 stpu some phrase as a message 所以在来自的帮助下这个答案 我在我的中创建了一个
  • 我应该在哪里放置数据库连接字符串以及如何处理连接池?

    我正在开发一个托管在 IIS 服务器上的 asp net 应用程序 要打开连接 我使用 SqlConnection con new SqlConnection Server INLD50045747A SQLEXPRESS Database
  • 加密货币、哈希值和密码问题,完全是菜鸟吗?

    我读过几篇关于这个主题的 stackoverflow 文章 特别是这个 PHP 密码的安全哈希和盐 但我还有一些问题 我需要一些澄清 请告诉我以下陈述是否属实并解释您的评论 如果有人可以访问您的数据库 数据 那么他们仍然需要弄清楚您的哈希算
  • 在 Ubuntu 上找不到 Tkinter 模块

    Python 2 7 1 r271 86832 Apr 11 2011 18 05 24 GCC 4 5 2 on linux2 Type help copyright credits or license for more informa
  • 加载自定义 True Type 字体

    在 Mac Firemonkey 应用程序 Delphi XE7 中 如何加载自定义 TrueType 字体 对于 Windows 我的应用程序安装程序将我的字体添加到 Windows 本身 我已经使用 FPC Lazarus 完成了此操作
  • 如何在搜索时添加加载图标? (Vue.js 2)

    我的组件是这样的
  • 内存对齐的目的

    不可否认 我不明白 假设您有一个内存 其内存字长度为 1 字节 为什么不能在未对齐地址 即不能被 4 整除 上的单次内存访问中访问 4 字节长的变量 就像对齐地址的情况一样 现代处理器上的内存子系统仅限于以其字大小的粒度和对齐方式访问内存