c++ - 结构与缓存行的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;
虚拟内存(或物理内存?)会像这样组织吗?
解决方案
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.
推荐阅读
- python - Python 代理请求永远不会通过
- node.js - 在 MERN 中插入数据时,req.body() 变空
- assembly - AVR 汇编中断向量表
- python - 字典值列表python的特定值的平均值
- python - 运行 pygame 时出现循环导入错误。我相信我正确导入了所有内容,但它一直给我一个问题
- mysql - 如何从具有 2 个列的给定 id 的另一个表中获取或连接数据
- javascript - ExpressJS 不在某些路由上应用 CSS
- java - 链表下一个属性
- python - Android Studio 不解析 Django 目录
- wordpress - 从用户 ID wordpress 获取订单 ID