簡體   English   中英

浮點精度可以依賴於線程嗎?

[英]Can floating-point precision be thread-dependent?

我在C#3.0中有一個基於struct的小型3D矢量類,它使用double作為基本單元。

一個例子:一個向量的y值是

-20.0 straight

我減去一個y值為的向量

10.094999999999965

y我期望的價值是

-30.094999999999963         (1)

相反,我得到了

-30.094999313354492         (2)

當我在一個單獨的線程中進行整個計算時,我得到(1)。 調試器和VS快速監視器也會返回(1)。 但是,當我在一個線程中運行幾次迭代然后從另一個線程調用該函數時,結果是(2)。 現在,調試器也返回(2)!

我們必須記住.NET JIT可能會將值寫回內存(網站Jon Skeet),這會將精度從80位(FPU)降低到64位(雙倍)。 但是,(2)的准確性遠低於此。

vector類看起來基本上都是這樣的

public struct Vector3d
{
  private readonly double _x, _y, _z;
  ...
  public static Vector3d operator -(Vector3d v1, Vector3d v2)
  {
      return new Vector3d(v1._x - v2._x, v1._y - v2._y, v1._z - v2._z);
  }  
}

計算就像這樣容易

Vector3d pos41 = pos4 - pos1;

是的,我相信結果可能是線程依賴的。

我的猜測是你在代碼中的某個時刻使用DirectX - 並且它設置了FPU的精度,我相信它是基於每個線程設置的。

要解決此問題,請在調用CreateDevice時使用D3DCREATE_FPU_PRESERVE標志。 請注意,這可能會對性能產生影響。 托管等效項是CreateFlags.FpuPreserve

(請參閱此相關問題 。我沒有建議將此作為副本關閉,因為它們表面上至少看起來有點不同。兩者都應該有助於答案可被發現。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM