首页 > 解决方案 > 结构与缓存行的x86内存对齐?

问题描述

最近我正在研究一个“搜索系统”,一些关于内存/缓存性能的东西让我感到困惑。假设我的机器信息:x86 arch(L1-3 缓存,64 字节缓存行),linux OS

CPU每次读取64字节(缓存行),CPU从内存地址(到缓存)读取数据总是64倍吗?例如0x00(到0x3F),0x40(到0x7f)。如果我需要位于 0x20 的数据(int32_t),那么系统仍然需要加载 0x00--0x3F。这种情况如何:
struct Obj{int64_t a[5];char b[2];};然后定义
int64_t c[5]; Obj obj; int64_t d;
虚拟内存(或物理内存?)会像这样组织吗?

在此处输入图像描述

标签: c++cx86memory-alignmentcpu-cache

解决方案


I think the part you might be missing is the alignment requirement that the compiler imposes for various types.

Integer types are generally aligned to a multiple of their own size (e.g. a 64-bit integer will be aligned to 8 bytes); so-called "natural alignment". This is not a strict architectural requirement of x86; unaligned loads and stores still work, but since they are less efficient, the compiler prefers to avoid them.

An aggregate, like a struct, is aligned according to the highest alignment requirement of its members, and padding will be inserted between members if needed to ensure that each one is properly aligned. Padding will also be added at the end so that the overall size of the struct is a multiple of its required alignment.

So in your example, struct Obj has alignment 8, and its size will be rounded up to 48 (with 6 bytes of padding at the end). So there is no need for 24 bytes of padding to be inserted after c[4] (I think you meant to write the padding at addresses 40-63); your obj can be placed at address 40. d can then be placed at address 88.

Note that none of this has anything to do with the cache line size. Objects are not by default aligned to cache lines, though "natural alignment" will ensure that no integer load or store ever has to cross a cache line.


推荐阅读