可以浮点precision线程依赖? [英] Can floating-point precision be thread-dependent?

查看:99
本文介绍了可以浮点precision线程依赖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小的3D矢量类在C#3.0的基础上,采用双重为基本单元结构。

举个例子:一个向量的Y值为

  -20.0直
 

我减去一个向量的y值

  10.094999999999965
 

y的我期望的值

  -30.094999999999963(1)
 

而我得到

  -30.094999313354492(2)
 

当我做了整个计算在一个单独的线程,我得到(1)。另外,调试器和VS快速手表返回(1)。但是,当我跑了几个迭代在一个线程中,然后调用函数从不同的线程,结果是(2)。现在,调试程序返回(2),以及<!/ P>

我们必须牢记.NET JIT可能会写的值回内存(网站乔恩斯基特),从而降低了精度为80位(FPU),以64位(双)。但是,(2)的准确度是远低于

Vector类基本上是这样

 公共结构的Vector3D
{
  私人只读双_x,_y,_z;
  ...
  公共静态的Vector3D运营商 - (的Vector3D V1,V2的Vector3D)
  {
      返回新的Vector3D(v1._x  -  v2._x,v1._y  -  v2._y,v1._z  -  v2._z);
  }
}
 

的计算是,因为这容易

 的Vector3D pos41 = POS4  -  POS1;
 

解决方案

是的,我相信结果可能是线程相关的。

我的猜测是,你正在使用的DirectX在您的code某一点 - 那设置precision为FPU,我相信它设置它在每个线程的基础

要解决此问题,使用 D3DCREATE_FPU_ $ P $当你调用pSERVE 标志 CreateDevice的。请注意,这将有可能影响性能。托管相当于是 CreateFlags.Fpu preserve

(请参见此相关的问题。我没有认为这一个被关闭作为一个重复,因为他们至少的一点表面上的不同。同时拥有应有助于回答被发现。)

I have a small 3D vector class in C# 3.0 based on struct that uses double as basic unit.

An example: One vector's y-value is

-20.0 straight

I subtract a vector with an y-value of

10.094999999999965

The value for y I would expect is

-30.094999999999963         (1)

Instead I get

-30.094999313354492         (2)

When I'm doing the whole computation in one single thread, I get (1). Also the debugger and VS quick-watch returns (1). But, when I run a few iterations in one thread and then call the function from a different thread, the result is (2). Now, the debugger returns (2) as well!

We have to keep in mind the .NET JIT might write the values back to memory (website Jon Skeet) which reduces the accuracy from 80 bit (FPU) to 64 bit (double). However, the accuracy of (2) is far below that.

The vector class looks basically like this

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);
  }  
}

The computation is as easy as this

Vector3d pos41 = pos4 - pos1;

解决方案

Yes, I believe the result can be thread-dependent.

My guess is you're using DirectX at some point in your code - and that sets the precision for the FPU, and I believe it sets it on a per-thread basis.

To fix this, use the D3DCREATE_FPU_PRESERVE flag when you call CreateDevice. Note that this will potentially have a performance impact. The managed equivalent is CreateFlags.FpuPreserve.

(See this related question. I haven't suggested that this one be closed as a duplicate, as they at least look a bit different on the surface. Having both should help the answer to be discoverable.)

这篇关于可以浮点precision线程依赖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆