使用内存屏障
在以下代码示例中,是否需要 FuncA 中的内存屏障来确保读取最新值?
class Foo
{
DateTime m_bar;
void FuncA() // invoked by thread X
{
Thread.MemoryBarrier(); // is required?
Console.WriteLine(m_bar);
}
void FuncB() // invoked by thread Y
{
m_bar = DateTime.Now;
}
}
编辑:如果没有,我如何确保 FuncA 读取最新值? (我想确保最近的值实际上存储在处理器的缓存中)[不使用锁]
In the following code sample, does the memory barrier in FuncA is required to ensure that the most up-to-date value is read?
class Foo
{
DateTime m_bar;
void FuncA() // invoked by thread X
{
Thread.MemoryBarrier(); // is required?
Console.WriteLine(m_bar);
}
void FuncB() // invoked by thread Y
{
m_bar = DateTime.Now;
}
}
EDIT: If not, how can I ensure that FuncA will read the most recent value? (I want to make sure that the recent value is actually store in the processor's cache) [wihout using locks]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
对我来说这似乎是一个很大的“不”。 Thread.MemoryBarrier() 仅同步实现它的线程内的内存访问。
来自 MSDN:
Looks like a big "No" to me. Thread.MemoryBarrier() only syncs up memory access within the thread that implemented it.
From MSDN:
我建议您将 Datetime 存储为刻度数(它的类型为“long”,即 Int64),您可以轻松地从刻度(new DateTime (ticks))转换为刻度(myDateTime.Ticks)。然后,您可以使用 Interlocked.Read 读取值并使用 Interlocked.Exchange 在快速非锁定操作中写入值。
I suggest you store Datetime as number of ticks (it is of type "long", i.e. Int64), you can easily transform from ticks (new DateTime (ticks)) and to ticks (myDateTime.Ticks). Then you can use Interlocked.Read to read value and Interlocked.Exchange to write value in fast non-locking operations.
是的,需要内存屏障,以便您可以获得最新的值。
如果内存屏障不存在,则线程 X 可以从其自己的缓存行读取 m_bar 的值,而该值尚未写回主内存(更改已在线程 Y 本地进行)。您可以通过将变量声明为 volatile 来达到相同的效果:
关于这个问题的一个很好的条目(可能是最好的)是 Joe Duffy 的这篇: 易失性读写和时效性
Yes, the memory barrier is needed so that you can get the most up to date value.
If the memory barrier is not present then it is possible for thread X to read the value of m_bar from its own cache line while that value hasn't been written back to main memory (the change has been make local to Thread Y). You can achieve the same effect by declaring the variable as volatile:
A good entry on that matter (probably the best) is this one by Joe Duffy: Volatile reads and writes, and timeliness
内存屏障实际上与 wat 锁定的作用相同,保证该字段将得到它的值
进入锁时内存中的最新值并在退出锁之前写入内存。
确保字段的值始终被读取或写入内存,并且永远不会通过读取或写入进行优化
它首先到cpu的缓存中也可以通过使用volatile关键字来实现。
除非原始整型和引用类型 DateTime 不能缓存在 CPU 寄存器中,所以
不需要(也不能)用 volatile 关键字声明。
A memory barrier does infact the same thing as wat locking does, guarantee the field will get its
latest value from memory on entering the lock and be written to memory before exiting the lock.
Making sure a field's value is always read or written to memory and never optimized by reading or writing
it first to the cpu's cache can also be achieved by using the volatile keyword.
Unless primitive integral types and reference types DateTime cannot be cached in CPU registers ad so
need not (and cannot) be declared with the volatile keyword.
这实际上并不重要,因为在 32 位架构上,在这种情况下读起来可能会被撕裂
This actually doesn't matter since on 32bit architectures one can get a torn read in such situation