最准确方式是读取/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size,x86-64通常为64字节,ARM64可能为64或128字节;lscpu中“min”值才是对齐依据,结构体须整体alignas(64)而非单字段。

直接读 /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size
这是最准、最轻量的方式,不需要安装额外工具,也不依赖内核缓存或用户态解析逻辑。x86-64 多数返回 64(单位字节),ARM64 可能是 64 或 128,取决于具体芯片。
执行命令即可:
cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size
-
index0对应 L1 数据缓存,其coherency_line_size就是硬件实际使用的缓存行大小 - 所有逻辑 CPU 的该值一致,查
cpu0足够 - 路径不存在?说明内核未暴露该接口(常见于极老内核或某些嵌入式平台),需 fallback 到
lscpu
lscpu 输出里的 Cache line sizes 怎么看
lscpu 显示的是“min / max”,但代码对齐必须按最小值来——因为缓存一致性协议(如 MESI)以最小粒度操作,填大了没用,填小了会 false sharing。
运行:
lscpu | grep "Cache line"
典型输出:
Cache line sizes: min: 64 bytes, max: 64 bytes
- 如果显示
min: 64, max: 128(某些 ARM 平台),仍必须用64对齐 -
lscpu读的是内核启动时缓存的拓扑信息,重启后才更新;/sys/是实时暴露的,更可信 - 容器里没装
util-linux?别硬依赖lscpu,优先走/sys
为什么不能只对结构体字段加 __attribute__((aligned(64)))
false sharing 发生在整条缓存行被多个核争抢时,不是单个字段。只对某个 uint64_t 字段对齐,无法阻止相邻字段落在同一缓存行里。
- 正确做法是对整个结构体对齐:
struct alignas(64) counter_t { ... }; - 对齐值必须是 2 的幂,且 ≥ 实际缓存行大小;填
64最安全(兼容 128 字节场景) - 若结构体总大小不足 64 字节,
alignas(64)会让它占满一整行;若超了,就跨行——这时得手动 padding 或拆分
查不到 coherency_line_size 时怎么 fallback
先确认是否真缺失:检查 /sys/devices/system/cpu/cpu0/cache/index0/ 是否存在,再看有没有 coherency_line_size 文件。没有的话,再试 lscpu;还不行,就得看 dmidecode -t cache(需 root)。
-
dmidecode输出里找LineSize字段,例如:LineSize: 64 bytes - 注意:虚拟机里
dmidecode可能返回模拟值,不反映物理 CPU 真实缓存行大小 - 别信
/proc/cpuinfo里的cache_alignment字段——它早已废弃,多数发行版不填
alignas 和 padding 都可能白做。


















