【发布时间】:2013-02-22 16:16:20
【问题描述】:
我正在使用 C# 并希望尽可能避免使用 unsafe 代码。如果我有一个大小可以填充缓存行的对象或数组,并且我想写入对象的每个字段或数组的索引,CPU 是否会在刷新写入行之前等待所有写入发生或当只有一个或几个写入发生时,它会提前刷新吗?
如果我只想在对行的所有写入都发生后才进行刷新,我应该在例程结束时快速连续地执行所有写入吗?我知道 CPU 和缓存一致性协议可能对此有所不同,我正在寻找一个普遍正确的经验法则答案。
【问题讨论】:
-
你在写什么,写到哪里,用什么写的?
-
不,你对此有错误的想法。一方面,您无法控制 .NET 对象如何跨越缓存行。您无法直接控制地址,GC 堆分配器可以做到这一点。 x86 上只有 4 个对齐,x64 上只有 8 个对齐,并且高速缓存行是 64 字节。此外,垃圾收集器压缩堆,因此地址可以随机更改。当缓存行即将被替换时,会发生回写。其他你不能直接影响自己的东西。
-
我知道我无法直接控制 GC 分配器如何分配我的对象,但我认为如果我有一个与缓存行大小相同的对象,那么我认为 GC 更有可能将整个对象加载到单个缓存行中,不是吗?分配器不太可能分解对象。如果 GC 想要移动它很好,但如果整个东西完全适合缓存行,我想 GC 不会在缓存行之间分解它,至少在大多数情况下不会。