使用内存屏障

发布于 2024-08-10 18:26:24 字数 407 浏览 5 评论 0原文

在以下代码示例中,是否需要 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一抹苦笑 2024-08-17 18:26:24

对我来说这似乎是一个很大的“不”。 Thread.MemoryBarrier() 仅同步实现它的线程内的内存访问。

来自 MSDN:

执行当前线程的处理器无法以这样的方式重新排序指令:调用 MemoryBarrier 之前的内存访问在调用 MemoryBarrier 之后的内存访问之后执行。

Looks like a big "No" to me. Thread.MemoryBarrier() only syncs up memory access within the thread that implemented it.

From MSDN:

The processor executing the current thread cannot reorder instructions in such a way that memory accesses prior to the call to MemoryBarrier execute after memory accesses that follow the call to MemoryBarrier.

洛阳烟雨空心柳 2024-08-17 18:26:24

我建议您将 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.

枫以 2024-08-17 18:26:24

是的,需要内存屏障,以便您可以获得最新的值。

如果内存屏障不存在,则线程 X 可以从其自己的缓存行读取 m_bar 的值,而该值尚未写回主内存(更改已在线程 Y 本地进行)。您可以通过将变量声明为 volatile 来达到相同的效果:

易失性修饰符通常用于被多个线程访问而不使用lock语句来串行化访问的字段。使用 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:

The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock statement to serialize access. Using the volatile modifier ensures that one thread retrieves the most up-to-date value written by another thread.

A good entry on that matter (probably the best) is this one by Joe Duffy: Volatile reads and writes, and timeliness

紅太極 2024-08-17 18:26:24

内存屏障实际上与 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.

浅浅淡淡 2024-08-17 18:26:24

这实际上并不重要,因为在 32 位架构上,在这种情况下读起来可能会被撕裂

This actually doesn't matter since on 32bit architectures one can get a torn read in such situation

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文