2010-05-17 24 views
6

Tengo una pequeña clase de vector 3D en C# 3.0 basada en la estructura que usa el doble como unidad básica.¿Puede la precisión de punto flotante ser dependiente del hilo?

Un ejemplo: valor de y uno de vector es

-20.0 straight 

que restar un vector con un valor de y

10.094999999999965 

El valor para y yo esperaría es

-30.094999999999963   (1) 

En su lugar obtengo

-30.094999313354492   (2) 

Cuando estoy haciendo todo el cálculo en un solo hilo, obtengo (1). También el depurador y VS quick-watch regresa (1). Pero, cuando ejecuto algunas iteraciones en un hilo y luego llamo a la función desde un hilo diferente, el resultado es (2). ¡Ahora, el depurador también regresa (2)!

Tenemos que tener en cuenta que .NET JIT puede escribir los valores de nuevo en la memoria (sitio web Jon Skeet) que reduce la precisión de 80 bits (FPU) a 64 bits (doble). Sin embargo, la precisión de (2) está muy por debajo de eso.

clase El vector se ve básicamente como esto

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

El cálculo es tan fácil como este

Vector3d pos41 = pos4 - pos1; 

Respuesta

5

Sí, creo que el resultado puede ser flujos dependientes.

Supongo que está usando DirectX en algún punto de su código, y eso establece la precisión para la FPU, y creo que lo establece por subproceso.

Para solucionar esto, utilice la marca D3DCREATE_FPU_PRESERVE cuando llame al CreateDevice. Tenga en cuenta que esto tendrá un impacto en el rendimiento. El equivalente administrado es CreateFlags.FpuPreserve.

(Ver this related question. No he sugerido que éste se cerrará como un duplicado, ya que al menos aspecto un poco diferente en la superficie. Tener ambos deben ayudar a que la respuesta sea visible.)

+0

Eso es cierto, estoy usando una biblioteca que crea un dispositivo Direct3D. ¡Gracias! ¿Hay alguna manera de establecer la precisión del CLR usted mismo, me refiero a Direct3D externo? – msteiger

+0

@ isometric-god: sospecho que existe, pero no lo sé. No creo que esto sea algo de CLR. Sospecho que es una propiedad general de "precisión para este hilo" para todo el código, administrado y no administrado. –

+0

No hay. El CLR hace suposiciones difíciles sobre la palabra de configuración de FPU. Hay una forma de restablecerlo, lanzar y atrapar una excepción. Por otra parte, ahora está en el estado incorrecto para el código de DirectX. –

Cuestiones relacionadas