当我尝试将游戏引擎的动画更新功能和物理模拟放入单独的线程中执行时,我意识到编写线程(动画,物理)之间的一些浮点值(例如对象的位置)的潜在竞争条件) 和读取线程(渲染器),如果两个线程要同时访问这些值。
我的问题是,考虑到即使浮点赋值也不是原子的,这种读写竞争条件是否会导致读者看到的原始平滑变化值的有线/突然变化?
此外,在我的情况下,我可以容忍少量的错误,因为这样的错误不会在下一个渲染帧中累积。
当我尝试将游戏引擎的动画更新功能和物理模拟放入单独的线程中执行时,我意识到编写线程(动画,物理)之间的一些浮点值(例如对象的位置)的潜在竞争条件) 和读取线程(渲染器),如果两个线程要同时访问这些值。
我的问题是,考虑到即使浮点赋值也不是原子的,这种读写竞争条件是否会导致读者看到的原始平滑变化值的有线/突然变化?
此外,在我的情况下,我可以容忍少量的错误,因为这样的错误不会在下一个渲染帧中累积。
根据我的理解,只要您一次只在线程上写入验证,并且您不在乎您的阅读线程是否使用最新版本,您就可以忽略竞争条件。
据我了解,编写浮点数对您的代码来说应该是原子的,尽管我认为这可能与平台有关。
ECMA-334 (C# 语言规范)第 12.5 节规定:
以下数据类型的读取和写入应是原子的:bool、char、byte、sbyte、short、ushort、uint、int、float 和引用类型。
为此,您不应该看到由于浮点数的读取和写入而导致的任何损坏(假设您在这里不是指双精度,这不能保证是原子写入)。
但是,应该注意的是,虽然值的写入保证是原子的,但读取/写入的顺序并不能保证,除非您使用特定的东西,例如调用Monitor.Enter。
Monitor.Enter 对此有点重,所以我建议在声明变量时使用volatile 关键字。假设这个变量的读/写是唯一需要发生的事情,它将保证读/写是按顺序完成的。
从理论上讲,如果在更新指数和更新尾数之间存在上下文切换,您可能会遇到很大程度的错误,但我怀疑当今使用的大多数平台或架构都允许这种事情发生。