- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
诚然,我不明白。假设您有一个内存,其内存字长度为 1 字节。为什么不能在未对齐地址(即不能被 4 整除)上的单次内存访问中访问 4 字节长的变量,就像对齐地址的情况一样?
最佳答案
现代处理器上的内存子系统仅限于以其字大小的粒度和对齐方式访问内存;造成这种情况的原因有很多。
现代处理器具有多层高速缓存,数据必须通过这些高速缓存进行提取;支持单字节读取将使内存子系统吞吐量与执行单元吞吐量紧密绑定(bind)(也称为 CPU 绑定(bind));这一切都让人想起PIO mode was surpassed by DMA出于许多与硬盘驱动器相同的原因。
CPU总是以其字大小读取(32位处理器上为4字节),因此当您在支持它的处理器上进行未对齐的地址访问时,处理器将读多个单词。 CPU 将读取您请求的地址跨越的每个内存字。这会导致访问请求数据所需的内存事务数量放大多达 2 倍。
因此,读取两个字节很容易比读取四个字节慢。例如,假设内存中有一个如下所示的结构:
struct mystruct {
char c; // one byte
int i; // four bytes
short s; // two bytes
}
在 32 位处理器上,它很可能会如下所示进行对齐:
处理器可以在一个事务中读取这些成员中的每一个。
假设您有该结构的打包版本,可能来自为了传输效率而打包的网络;它可能看起来像这样:
读取第一个字节将是相同的。
当您要求处理器为您提供 0x0005 中的 16 位时,它将必须从 0x0004 中读取一个字并左移 1 个字节以将其放入 16 位寄存器中;一些额外的工作,但大多数都可以在一个周期内完成。
当您从 0x0001 请求 32 位时,您将获得 2 倍的放大。处理器将从 0x0000 读入结果寄存器并左移 1 个字节,然后再次从 0x0004 读入临时寄存器,右移 3 个字节,然后与结果寄存器进行“或”操作。
对于任何给定的地址空间,如果架构可以假设 2 个 LSB 始终为 0(例如,32 位机器),那么它可以访问 4 倍以上的内存(2 个保存的位可以代表 4 个不同的状态),或者相同数量的内存,具有 2 位,用于标记等内容。从地址中去掉 2 个 LSB 将得到 4 字节对齐;也称为stride 4 字节。每次地址递增时,实际上是递增位 2,而不是位 0,即最后 2 位将始终为 00
。
这甚至会影响系统的物理设计。如果地址总线需要减少 2 个位,则 CPU 上的引脚可以减少 2 个,电路板上的走线也可以减少 2 个。
CPU 可以原子地对内存的对齐字进行操作,这意味着没有其他指令可以中断该操作。这对于许多人的正确操作至关重要lock-free data structures及其他concurrency范式。
处理器的内存系统比此处描述的要复杂得多,也更复杂;关于how an x86 processor actually addresses memory的讨论可以提供帮助(许多处理器的工作原理类似)。
遵守内存对齐还有更多好处,您可以在 this IBM article 中阅读。 .
计算机的主要用途是转换数据。现代内存架构和技术经过数十年的优化,有助于以高度可靠的方式在更多、更快的执行单元之间输入、输出更多数据。
我之前提到的另一个性能对齐是缓存行的对齐(例如,在某些 CPU 上)64B。
有关利用缓存可以获得多少性能的详细信息,请查看 Gallery of Processor Cache Effects ;从这里question on cache-line sizes
Understanding of cache lines can be important for certain types of program optimizations. For example, the alignment of data may determine whether an operation touches one or two cache lines. As we saw in the example above, this can easily mean that in the misaligned case, the operation will be twice slower.
关于memory - 内存对齐的目的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59372376/
我正致力于通过 OAuth 合并外部 API,但对 expires_in 属性的用途有点迷惑。通过阅读,应该对 api token 的使用进行防御性编码,因为您应该预料到 token 在任何时候都可能
有人可以概述或总结一下 Spring 框架上下文中 bean 的用途吗? 我了解标准的 Java bean(没有 arg 构造函数、getter/setter,通常是序列化的),但 Spring be
使用 OpenGL 4.1 和 ARB_separate_shader_objects,我们能够在着色器程序中存储着色管道的不同阶段。众所周知,要使用这些,我们需要将它们附加到程序管道对象,然后绑定(
正如我从文档中了解到的那样,“MoveIteratorFactory”的目的是生成每一步都需要执行的 Action 。 “getSize”方法的移动子集有多大? “createOriginalMove
请解释 CMakeLists.txt 中这一行的目的是什么: 包括(InstallRequiredSystemLibraries) 我在 CMake 示例中看到这一行,但找不到好的解释,为什么我需要它
这里是新手。我仍在尝试理解在多个布局中运行单个进程或目的的概念。 例如,我想在我的申请中添加“提交后”功能。有一个包含标题、内容等文本框的主布局,以及一个链接到另一个布局以选择类别的按钮。我的问题是,
我在看 Box Oauth2.0 View Controller : https://github.com/box/box-ios-sdk-v2/blob/master/BoxSDK/OAuth2/B
我编写了一个将字符串复制到系统剪贴板的 Java 应用程序。构造函数使用 Clipboard.setContents(Transferable contents, ClipboardOwner own
阅读此文后:http://sourcemaking.com/design_patterns/command 我还是不太明白为什么我们需要这个。 最佳答案 想法是,如果命令被封装为对象,那么这些命令可以
我知道 c++ 中的模板是做什么的,但是今天我看到了一些奇怪的代码: template <> void swap(foo &a, foo &b) { a.name = b.name; a.
我不太明白 C# Collections 中 IEnumerator 的用途是什么。它的用途是什么,为什么要使用它? 我试着在线查看 http://msdn.microsoft.com/en-us/l
不幸的是,我今天做了一些代码考古(同时重构了一些旧的危险代码)并发现了这样的小化石: # line 7 "foo.y" 能在里面找到如此古老的宝藏,我完全惊呆了。我在 C 编程的网站上阅读了它。然而,
您能否澄清一下此注释的实际用途? - 如果我们没有使用数据库中的 SQL 表定义定义相应的约束,会发生什么情况。当我们尝试插入时,hibernate 会检查唯一性吗?或者这就是DB的目的吗?如果 hi
我在视频教程中看到过这段代码: const navToggle = ["Menu"].join(""); $(".site-header").prepend(navToggle); 我明白它的基本作用
我想知道这个成员函数的 scroll_to(TextBuffer::iterator& iter, double within_margin = 0)参数 within_margin。 API 是这样
我想知道是否可以将子目录提交到目录例如,假设您有 site.com/directory 可以将子目录提交到目录。我即将开始为希望她的网站在搜索引擎中排名靠前的客户进行一些搜索引擎优化。我知道实现此目的
STL 迭代器的用途是什么?为什么程序员要创造这个概念? 最佳答案 迭代器允许您将算法与容器分开。只要您有开始和结束迭代器,并且知道迭代器的功能(随机访问等),您就可以在迭代器指定的范围内进行操作。例
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&respons
我正在编写代码,使用通用的 linux i2c 驱动程序 linux/i2c-dev.h 实现一个简单的 i2c 读/写功能 我对 ioctl 感到困惑:I2C_SLAVE 内核文档说明如下: You
在尝试克隆可变集合时,我最初的方法是对 mutable.Cloneable 特征使用 clone() 方法。但是,这取决于创建引用副本的 java.Object.clone 实现,而不是深拷贝。通过测
我是一名优秀的程序员,十分优秀!