Tag: 内存 防护

在哪里放置围栏/内存屏障以保证新的读取/提交写入?

像许多其他人一样,我一直对易失性读/写和围栏感到困惑。 所以现在我想完全理解这些是做什么的。 因此,易失性读取应该(1)表现出获取语义,(2)保证读取的值是新鲜的,即它不是缓存值。 让我们关注(2)。 现在, 我已经读过 ,如果你想执行一个易失性读取,你应该在读取后引入一个获取栅栏(或一个完整的栅栏),如下所示: int local = shared; Thread.MemoryBarrier(); 这究竟是如何阻止读取操作使用以前缓存的值? 根据栅栏的定义(不允许读取/存储在栅栏上方/下方移动),我会在读取之前插入栅栏,防止读取穿过栅栏并及时向后移动(也就是说,缓存)。 如何防止读取被及时向前移动(或后续指令被及时向后移动)保证了易失性(新鲜)读取? 它有什么用? 类似地,我认为易失性写入应该在写入操作之后引入栅栏,从而阻止处理器及时向前移动写入(也就是说,延迟写入)。 我相信这会使处理器刷新对主内存的写入。 但令我惊讶的是, C#实现在写入之前引入了栅栏! [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref int address, int value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } 更新 根据这个例子 ,显然是从“坚果壳中的C#4”中取出的, 在写入之后放置的栅栏2应该强制写入立即刷新到主存储器,并且在读取之前放置的栅栏3应该保证一个新的阅读: class […]