在写一篇关于未对齐/对齐的直接内存访问的博客文章时,我遇到了一个我很难解释的结果:如果我的内存访问与前 4 个字节对齐,我发现当数据结构适合 L1 时,性能会出现明显的差异缓存。在某些情况下,其他位置的速度要快 20%。
这篇文章详细介绍了实验和方法,但这里是总结:
- 分配一块适合 L1 的内存(在我的笔记本电脑上为 32k,使用 hwloc/检查您的 cpu 的规格以找出答案)。将块与缓存线大小对齐(通常为 64b,检查您的硬件)。分配是预先完成的,而不是衡量的。
- 遍历内存块并将 long(某个值)写入给定偏移量的每个高速缓存行(如果偏移量不是 8 的倍数,则有效地导致未对齐的写入)。
- 遍历内存块并从相同的偏移量读取并验证该值是否符合预期。
为什么偏移量为0-3时性能会有任何差异?
测量代码的本质(根据评论中的要求):
for (address = startingAddress; address < limit; address += CACHE_LINE_SIZE) {
Unsafe.putLong(address, value);
}
for (address = startingAddress; address < limit; address += CACHE_LINE_SIZE) {
if (Unsafe.getLong(address) != value)
throw new RuntimeException();
}
其中起始地址是缓存对齐+偏移量。完整的实验在这里可用: