2013-02-28 4 views
9

x90 FPU отличается тем, что использует внутренний 80-битный прецизионный режим, что часто приводит к неожиданным и невоспроизводимым результатам для всех компиляторов и машин. In my search для воспроизводимой математики с плавающей запятой в .NET. Я обнаружил, что обе основные реализации .NET (Microsoft и Mono) генерируют команды SSE, а не x87 в режиме 64-бит.Является ли SSE с плавающей запятой арифметикой воспроизводимой?

SSE (2) использует строго 32-разрядные регистры для 32-битных поплавков и строго 64-разрядные регистры для 64-битных поплавков. Денормалы можно по желанию сбросить до нуля, установив appropriate control word.

Таким образом, было бы очевидно, что SSE не страдает от связанных с точностью вопросов x87 и что единственной переменной является денормальное поведение, которое можно контролировать.

Оставляя в стороне вопрос о трансцендентных функциях (которые не предусмотрены SSE в отличие от x87), использует ли SSE воспроизводимые результаты для машин и компиляторов? Могут ли, например, оптимизация компилятора перевести на разные результаты? Я нашел несколько противоречивых мнений:

Если у вас есть SSE2, используйте его и живите долго и счастливо. SSE2 поддерживает операции 32b и 64b, а промежуточные результаты имеют размер операндов . - Йосси Крейнин, http://www.yosefk.com/blog/consistency-how-to-defeat-the-purpose-of-ieee-floating-point.html

...

инструкции SSE2 (...) полностью IEEE754-1985 уступчивый, и они позволяют лучше воспроизводимости (благодаря статическому округлением ) и переносимость с другими платформами. Мюллер и др aliis, Handbook of Floating-Point Arithmetic - с.107

однако:

Кроме того, вы не можете использовать SSE или SSE2 для чисел с плавающей точкой, потому что это слишком при заданных детерминированным , - Джон Watte http://www.gamedev.net/topic/499435-floating-point-determinism/#entry4259411

+1

Я уверен, что если в Интернете возникнут два противоречивых мнения, вы получите здесь аргумент (и, вероятно, по крайней мере, третье мнение) – KevinDTimm

+1

@KevinDTimm, который не делает этот вопрос субъективным. SSE является либо воспроизводимым, либо нет. – Asik

+1

«SSE или SSE2 [слишком] недостаточно определены, чтобы быть детерминированным». Я не претендую на то, чтобы быть экспертом по этим вопросам, но для меня это звучит как BS. В ссылке есть разговоры о библиотечных функциях для трансцендентальных и, конечно, могут быть ошибки в тех, кто находится на одной платформе, а не в другой, как это может быть (на самом деле, возможно, есть) в любом оптимизаторе компилятора, но это ничего не говорит о SSE/SSE2 как таковой. Имеет ли он пример того, что он имеет в виду? –

ответ

9

SSE полностью указано *. Мюллер является экспертом в арифметике с плавающей запятой; кто ты будешь доверять, его или какого-то парня на форуме гамедева?

(*) на самом деле существует несколько исключений для операций, отличных от IEEE-754, таких как rsqrtss, где Intel никогда не полностью определяла поведение, но это не влияет на основные операции IEEE-754, и, что более важно, их поведение может На самом деле это изменение изменилось, потому что он нарушил бы двоичную совместимость для слишком многих вещей, поэтому они так же хороши, как указано.

3

Как отметил Стивен, результаты, полученные в данной части кода сборки SSE, будут воспроизводимыми; вы кормите тот же код одним и тем же входом и получаете тот же результат в конце. (То есть, цитата Джона Уотта неверна.)

Вы бросили там слово «компиляторы». Это совсем другая игра в мяч. Многие компиляторы по-прежнему очень плохо сохраняют правильность кода с плавающей запятой.(The ATLAS errata page упоминает, что clang «не позволяет создать правильный код для некоторых операций».) Если вы используете специальные функции в своем коде, вы также в какой-то степени пощадите тех, кто выполнил вашу математическую библиотеку.

Смежные вопросы