【问题标题】:Does Volatile.Read / Volatile.Write for "double" atomic?Volatile.Read / Volatile.Write 是否为“双”原子?
【发布时间】:2022-01-26 10:29:13
【问题描述】:

MSDN 声明

long、ulong、double 和 decimal,以及用户定义的类型,不保证是原子的 5.5 Atomicity of variable references

Volatile.Write Method (Double%, Double) 会作为原子操作工作吗?如果可以,如何保证?

在一个线程中执行Volatile.Write(ref mydouble, value); 并在另一个线程中执行Volatile.Read(ref mydouble) 是否安全,其中mydouble 具有double 类型?

这是一般性问题。另一个问题 - 在这种特殊情况下我应该怎么做:

  • 2 处理器 Xeon x64 服务器
  • Windows + MS .NET 4.5
  • 从不同线程读取/写入双重
  • 最小延迟(需要最小,因为我正在编写 HFT 软件)

【问题讨论】:

    标签: c# .net-4.5


    【解决方案1】:

    不,Volatile 不是原子的,在 SMP(>1 处理器)系统中假设是不安全的。它在单处理器机器上是安全的。

    除非您真的需要性能,否则您可能需要InterlockedInterlocked.ExchangeInterlocked.Read

    【讨论】:

    • @javapowered 个人,我不知道任何保证“易失性”(双)暗示原子。因此,如果我进行无锁访问,我个人会使用“互锁”。事实上,即使在 x64 上也可以使用 Interlocked,其中(作为芯片大小的副作用)它几乎肯定 是原子的。因此,我不得不同意“使用联锁”是该问题的最合适答案。
    • @MarcGravell 什么时候应该使用“Volatile”类?它变得无用。总是使用“联锁”吗?
    • 如果你引发了一个 single 额外的页面错误,它实际上会抹去 数万 个 Volatile 调用的收益。页面错误和优化内存局部性(即数组与列表)将为您带来更多性能优势。阅读 XNA 人们推荐的一些优化内容,他们有很多关于这方面的好东西。
    • @MarcGravell 我认为这是一个常见的误解,即人们认为 Interlocked 对于大于 32 位的值不是原子的,因为 MSDN 文档中有一个声明。然而,这一切都取决于它运行的架构。如果在 x64 上运行,Interlocked 对于 64 位值类型是原子的。我在很大程度上怀疑 volatile 是相同的(即 x64 系统上双/长/8 字节值类型的原子)。更多在这里,albahari.com/threading/part4.aspx。 PS 我通过查看调用的 API 得出了这个结论,我 100% 确定 Interlocked 对于 x64 上的 8 字节值是原子的
    • @PaulBetts 你有关于 XNA 推荐优化的好链接吗?
    猜你喜欢
    • 2021-10-25
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多