【问题标题】:Is it safe to ignore the read-write race condition of a smoothly changing floating point value?忽略平滑变化的浮点值的读写竞争条件是否安全?
【发布时间】:2010-02-26 07:16:39
【问题描述】:

当我尝试将游戏引擎的动画更新功能和物理模拟放入单独的线程中执行时,我意识到编写线程之间的一些浮点值(例如对象的位置)的潜在竞争条件(如果两个线程要同时访问这些值,则动画、物理)和读取器线程(渲染器)。

我的问题是,即使浮点赋值也不是原子的,这样的读写竞争条件是否会导致读者看到的原始平滑变化值的有线/突然变化?

此外,在我的情况下,我可以容忍少量的错误,因为这样的错误不会在下一个渲染帧中累积。

【问题讨论】:

  • 我建议您指定您的平台和语言,因为我们无法在不知道这些的情况下对浮点表示做出任何保证。

标签: multithreading game-engine


【解决方案1】:

就我的理解而言,只要您一次只在线程上写入验证,并且您不在乎您的阅读线程是否使用最新版本,您就可以忽略竞争条件。

根据我的理解,编写浮点数对您的代码来说应该是原子性的,尽管我认为这可能取决于平台。

【讨论】:

    【解决方案2】:

    Section 12.5 of ECMA-334(C# 语言规范)声明:

    读取和写入以下数据 类型应为原子类型:bool、char、 字节,sbyte,短,ushort,uint,int, 浮点数和引用类型。

    为此,您不应该看到由于浮点数的读取和写入而导致的任何损坏(假设您在这里不是指双精度,即不保证是原子写入)。

    但是,应该注意的是,虽然值的写入保证是原子的,但读取/写入的顺序是不保证的,除非您使用特定的东西,例如调用到Monitor.Enter。

    Monitor.Enter 对此有点重,所以我建议在声明变量时使用volatile keyword。假设这个变量的读/写是唯一需要发生的事情,它将保证读/写是按顺序完成的。

    【讨论】:

      【解决方案3】:

      从理论上讲,如果在更新指数和更新尾数之间发生上下文切换,您可能会遇到很大程度的错误,但我怀疑当今使用的大多数平台或架构都允许这种情况发生。

      【讨论】:

      • 您只是在谈论多个线程之间的一个 cpu 案例“上下文切换”。在 PC 或 xbox360 等共享内存架构上,不同 CPU 上的多个线程可以同时访问同一内存。
      • 我在谈论任何现代平台。如果可以在物理写入的中间读取浮点值,我会有些惊讶。我希望在该过程中总线或缓存或 something 将被锁定,以便指令正确完成。但进一步的证据将是有用的。
      猜你喜欢
      • 1970-01-01
      • 2016-07-22
      • 2017-03-20
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2018-08-07
      • 2021-02-03
      相关资源
      最近更新 更多