取消引用字段时是否需要内存屏障(.net x86 或 x64)?

发布于 2024-10-12 13:11:43 字数 1044 浏览 9 评论 0原文

在如下代码中,如果 Proc1 和 Proc2 在不同的处理器上同时执行,ThingVal2 是否有可能获得 5 以外的值(例如零)?

Class SimpleThing
    Public X As Integer
    Sub New(ByVal value As Integer)
        X = value
    End Sub
End Class
Class ConcurrencyTest
    Dim Thing1 As New SimpleThing(5)
    Dim Thing2 As New SimpleThing(0)
    Dim ThingRef As SimpleThing = Thing1
    Dim ThingVal1, ThingVal2 As Integer
    Sub Proc1()
        Thing2.X = 5
        Threading.Thread.MemoryBarrier()
        ThingRef = Thing2
    End Sub
    Sub Proc2()
        ThingVal1 = Thing2.X
        ThingVal2 = ThingRef.X
    End Sub
End Class

我知道在像 IA64 这样的弱模型中,Proc2 很可能会认为 ThingRef 已经发生了变化,但没有看到 Thing2 的字段 X 已经发生了变化。在 x86 或 x64 上运行的 .Net 应用程序是否存在这种风险?如果 Proc1 创建了 SimpleThing 的新实例,将其 X 字段设置为 5,然后将 ThingRef 设置为指向它,这是否足以避免危险,或者新事物可能会分配在缓存行上是否与 Proc2 线程访问过的其他内容共享?

多线程代码的常见范例是构造一个不可变对象并设置一个指向它的可变引用(可能使用 Interlocked.CompareExchange)。在 x86/x64 下读取不可变类型而不考虑线程总是安全的,还是会导致问题?如果是后者,vb.net 中保证可靠行为的首选方式是什么?

另外,是否有任何方法可以指定代码必须以不会发生此类问题的方式运行(例如,将执行限制为 IA64 等单核,否则无法保证正确操作)?

In code like the following, if Proc1 and Proc2 execute simultaneously on different processors, is it possible for ThingVal2 to get a value other than 5 (e.g. zero)?

Class SimpleThing
    Public X As Integer
    Sub New(ByVal value As Integer)
        X = value
    End Sub
End Class
Class ConcurrencyTest
    Dim Thing1 As New SimpleThing(5)
    Dim Thing2 As New SimpleThing(0)
    Dim ThingRef As SimpleThing = Thing1
    Dim ThingVal1, ThingVal2 As Integer
    Sub Proc1()
        Thing2.X = 5
        Threading.Thread.MemoryBarrier()
        ThingRef = Thing2
    End Sub
    Sub Proc2()
        ThingVal1 = Thing2.X
        ThingVal2 = ThingRef.X
    End Sub
End Class

I know that in a weak model like IA64, there is a real possibility that Proc2 might see ThingRef as having changed but not see field X of Thing2 as having done so. Does that risk exist for a .Net application running on x86 or x64? If Proc1 created a new instance of SimpleThing, set its X field to 5, and then set ThingRef to point to it, would that be sufficient to avoid danger, or would it be possible that the new thing might be allocated on a cache line which was shared with something else that the Proc2 thread had accessed?

A common paradigm with multi-threaded code is to construct an immutable object and set a mutable reference to point to it (possibly using Interlocked.CompareExchange). Is it always safe under x86/x64 to read an immutable type without regard to threading, or can that cause problems? If the latter, what's the preferred way in vb.net to guarantee reliable behavior?

Also, is there any way of specifying that code must run in a way where such problems could not occur (e.g. limiting execution to a single core on something like an IA64 which could not otherwise guarantee correct operation)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

挖鼻大婶 2024-10-19 13:11:44

好吧,你提了很多问题。我会尝试回答我所知道的。

-1。广告您的代码示例:

CLR 自 2.0 起已订购商店。这意味着您的 ThingVal 在 x86/x64 上将始终为 5。一定。我没有在真正的 IA64 上尝试过它,但它应该在 IA64 上也能正常工作,因为 CLR 应该确保在所有平台上进行有序写入,并且对于您的简单示例来说应该足够了。

-2。 IA64 与 x86/x64:

x86/x64 具有不同的内存语义,并且不存在像 IA64 那样的风险。这里唯一可能的问题是,您实际上使用的是更高级的语言,如果它使用优化编译器(如 C++ 那样),您在不确切知道编译器如何进行优化的情况下无法预测任何事情。未记录:VB 不执行任何全局优化等,因此您的代码应该是安全的。

-3。 ad 不可变:

如果你真的只是阅读它并且它确实是不可变的,那么它是安全的。

-4。 ad单核:

可以设置线程亲和性。它是每个线程的标准属性,定义线程可以在哪些 CPU 上运行。 (.net的线程亲和力设置直接改变了操作系统的亲和力。)但是它会使你的程序运行缓慢。

另外,您可以切换到 C# 并使用 volatile 关键字。它将帮助您生活得更轻松,因为它使所有 CPU 都能立即看到 易失性变量的任何更改,从而解决您在此处提出的所有可能的问题。不幸的是,VB不提供这个关键字。

OK, you gave many questions. I'll try to answer what I know.

-1. ad your code example:

CLR since 2.0 has ordered stores. It means that your ThingVal will always be 5 on x86/x64. For sure. I didn't tried it on a real IA64, but it should work as well on IA64, because CLR should ensure ordered writes on all platforms and should be enough for your simple example.

-2. ad IA64 vs x86/x64:

x86/x64 has a different memory semantics and there is no such risk like on IA64. The only possible problem here is that you are actually using a higher level language and if it used an optimizing compiler (like C++ does) you cannot predict anything without knowing exactly how the compiler do its optimizations. Undocumented: VB doesn't perform any global optimizations etc. so your code should be safe.

-3. ad immutable:

If you really just read it and it is really immutable, it is safe.

-4. ad single core:

You can set the thread affinity. It is a standard property of each thread and defines on which CPUs the thread can run. (Thread affinity setting of .net directly alters the affinity in operating system.) But it makes your program run slowly.

Also, you can switch to C# and use volatile keyword. It will help you to live easier, as it makes any changes to volatile variable immediately seen by all CPUs and that in turn will solve all the possible problems you presented here. Unfortunately, VB doesn't provide this keyword.

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