Точность с плавающей точкой может быть зависимой от потока?

У меня есть маленький 3D векторный класс в C# 3.0 на основе структуры, которая использует дважды в качестве основной единицы.

Пример: y-значение Одного вектора

-20.0 straight

Я вычитаю вектор с y-значением

10.094999999999965

Значение для y, который я ожидал бы,

-30.094999999999963         (1)

Вместо этого я добираюсь

-30.094999313354492         (2)

Когда я делаю целое вычисление в одном единственном потоке, я добираюсь (1). Также отладчик и возвраты быстрых часов VS (1). Но, когда я выполняю несколько повторений в одном потоке и затем вызываю функцию от другого потока, результат (2). Теперь, возвраты отладчика (2) также!

Мы должны иметь в виду, что JIT.NET мог бы записать значения обратно к памяти (веб-сайт Jon Skeet), который уменьшает точность от 80 битов (FPU) к 64 битам (дважды). Однако точность (2) далека ниже этого.

Векторный класс в основном походит на это

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;
6
задан msteiger 17 May 2010 в 09:28
поделиться

1 ответ

Да, я считаю, что результат может зависеть от потока.

Я предполагаю, что вы используете DirectX в какой-то момент своего кода - и он устанавливает точность для FPU, и я считаю, что он устанавливает ее для каждого потока.

Чтобы исправить это, используйте флаг D3DCREATE_FPU_PRESERVE при вызове CreateDevice . Обратите внимание, что это потенциально может повлиять на производительность. Управляемый эквивалент - CreateFlags.FpuPreserve .

(См. этот связанный вопрос . Я не предлагал закрыть этот как дубликат, поскольку они, по крайней мере, внешне выглядят немного иначе. И то, и другое должно быть помогите найти ответ.)

5
ответ дан 17 December 2019 в 04:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: