【发布时间】:2018-07-08 16:23:39
【问题描述】:
我读到在 g++ 中我们可以做到:
struct foo {
int a, b, c;
} __attribute__((__aligned__(64)));
因此 struct foo 的大小为 64 --- 这通常是缓存行的大小。当我们需要访问这个缓存行时,cpu可以一次性加载foo。
这是否意味着 CPU 可以在任何内存地址从 L2 加载 foo --- 不一定是 64 的整数?
假设 foo 在内存中的地址类似于 0xFFFF3,CPU 是否需要读取两条缓存线才能加载 foo?
谁能帮我澄清一下?
PS:我在 CentOS 64bit 上使用 g++ 6.2
【问题讨论】:
-
我不是最新 C++ 语言标准细节方面的专家,但在过去,大多数编译器允许您对不同数据类型的对齐要求进行一些控制。原因是,在某些架构(例如 x86)上需要权衡:将结构打包得更紧密,程序运行速度会变慢,但数据占用的空间会更少。这是应允许应用程序开发人员做出的决定。
-
@jameslarge 为什么结构更紧密而程序运行更慢?我的想法正好相反:打包结构会减少缓存未命中,因此程序运行得更快。
-
一个 64 位 x86-64 操作数可以位于任何字节地址,但如果地址不是,CPU 将不得不执行 两次 缓存操作来获取/存储它8 的倍数。如果在结构中混合不同大小的字段,则根据编译选项,编译器可能需要使用 padding(结构中未使用的空间)来使每个字段对齐其首选边界。如果您使用编译器选项,即“无填充”,那么您将获得更小的结构,但某些字段只能通过双重提取/存储来访问。对于某些架构,“无填充”甚至不是一个选项。
标签: c++ caching memory memory-management g++