представление вещественных чисел в Visual Studio
От: sergey2b ЮАР  
Дата: 01.07.20 14:29
Оценка:
я раньше встречал упоминание, что CPU обрабатывает вещественные числе представленные в double
и при использовании float перед каждой операцией происходит преобразование типа числа

судя по этому документы это уже не так IEEE Floating-Point Representation

какой вещественный тип лучше использовать с точки зрения оптимизации по скорости
Отредактировано 01.07.2020 14:30 sergey2b . Предыдущая версия .
Re: представление вещественных чисел в Visual Studio
От: LaptevVV Россия  
Дата: 01.07.20 15:43
Оценка: 6 (1)
S>судя по этому документы это уже не так IEEE Floating-Point Representation
Студия здесь не при делах.
По указанному адресу описан стандарт IEEE-754.
Который и реализован в микропроцессоре.
Более того, все операции с плавающей точкой происходят на плавающих регистрах, которые еще и устроены в виде стека.
Размер регистра = 80 бит, 64 бита мантисса, 15 бит — порядок.
При загрузке в регистр и float, и double расширяются до 80 бит.
Но в интеле есть еще много других регистров, которые тоже работают с плавающими числами.
Например, ХMM.
А чего там в системе команд AVX сделано, я даже и не знаю.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: представление вещественных чисел в Visual Studio
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.07.20 16:30
Оценка: 12 (2) +1
Здравствуйте, sergey2b, Вы писали:

S>я раньше встречал упоминание, что CPU обрабатывает вещественные числе представленные в double

S>и при использовании float перед каждой операцией происходит преобразование типа числа

Вашему описанию соответствуют две совершенно разные вещи.

Первая — это как вещественные числа представляются в CPU во время операций с ними и при хранении в своих регистрах. В случае x86, в 32-битном режиме нормой было использование FPU, у которого внутренний формат с 64 битами мантиссы (это даже не double, это то, что в нормальных местах зовётся long double). Вычисления производятся с ним, но результаты могут округляться на каждой операции до одинарной или двойной точности. Этот режим рулится у MS через функции типа _control87, умолчание, насколько помню — усечение до double.
В x86-64 студия, судя по документации, использует только SSE, у которого раздельные операции для одинарной и двойной точности, при этом long double зачем-то сделано алиасом для double, то есть FPU из C/C++ не применить совсем.
В Linux и близких системах такого тупого форсирования нет, есть только предпочтение — FPU в 32 битах и SSE в 64 (обычно можно крутить опциями компиляции).

Вторая — это выполняется ли в C правило, что float при любой арифметической операции преобразуется в double. Это правило было в K&R, отменено точно в C99, но я не знаю с ходу про промежуточные стадии и про реализацию у таких своенравных авторов, как MS.

S>судя по этому документы это уже не так IEEE Floating-Point Representation


S>какой вещественный тип лучше использовать с точки зрения оптимизации по скорости


float (одинарный), почти всегда. Даже если операции делаются одинаково, меньше возни с памятью.
The God is real, unless declared integer.
Re[2]: представление вещественных чисел в Visual Studio
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.07.20 16:52
Оценка: 12 (2) +1
Здравствуйте, LaptevVV, Вы писали:

S>>судя по этому документы это уже не так IEEE Floating-Point Representation

LVV>Студия здесь не при делах.

При делах.

LVV>По указанному адресу описан стандарт IEEE-754.

LVV>Который и реализован в микропроцессоре.

Вы плохо читаете. Там написаны совершенно конкретные вещи (местами очень характерно неправильные):
— "Microsoft C++ (MSVC) is consistent with the IEEE numeric standards." (всем? предложение явно некорректно).
— чему соответствуют float и double компилятора (тут ok — и в этом главная полезная конкретика документа).
— чему соответствует long double компилятора (в первый раз — что он равен double во внешнем хранении — "long double data type is treated as a distinct type, but the storage type maps to double" — то есть нафиг такой не нужен, но чуть ниже говорится про 15 бит порядка и 64 мантиссы (significand) — то есть сами себе противоречат).
— "There are at least five internal formats for floating-point numbers that are representable in hardware targeted by the MSVC compiler." Судя по списку — сюда включён quadruple-precision (128 бит), который на x86 обычно не водится (PPro не считаем) — значит, врут про поддержку железа (хотя раз компилятор не умеет — то пофиг, для юзера студии ничего не меняется).
— Что IEEE описывает "double-extended-precision (10-byte) format" — врут. На самом деле, да, есть "extended double" как рекомендация по минимальным свойствам параметров таких типов, но не конкретная реализация (никто там не обязан укладывать его в 10 байт, не использовать скрытую единицу, и так далее).

Дальше, да, идёт информация из IEEE754. Но эта начальная часть, написанная словно тем журналистом, которого изнасиловали учёные авторы реальных описаний, очень показательна для MS — и приводит в итоге к очень простому выводу — не используйте ничего кроме float и double, иначе вас укусят за бочок, причём в самый неожиданный момент. А для standard lawyerʼа это, кроме примера как не надо писать, ещё и показательнейший документ о подводных течениях и историческом развитии.

LVV>Более того, все операции с плавающей точкой происходят на плавающих регистрах, которые еще и устроены в виде стека.


И это никак не меняет суть самих вычислений.

LVV>Размер регистра = 80 бит, 64 бита мантисса, 15 бит — порядок.

LVV>При загрузке в регистр и float, и double расширяются до 80 бит.

А потом сужаются, при выгрузке. А ещё могут округляться по ходу вычислений. И это куда важнее, чем просто расширенное хранение.

LVV>Но в интеле есть еще много других регистров, которые тоже работают с плавающими числами.


Регистры с числами не работают, они их хранят. С числами работают инструкции.

LVV>Например, ХMM.

LVV>А чего там в системе команд AVX сделано, я даже и не знаю.

Ну тогда я вам подскажу: AVX работает с теми же типами данных теми же операциями, что SSE — с float и double, на тех же XMM регистрах (могут их расширять в AVX2 и AVX512, тип данных сохраняется). 80-битного формата там нет.
The God is real, unless declared integer.
Re[2]: представление вещественных чисел в Visual Studio
От: watchmaker  
Дата: 01.07.20 19:37
Оценка:
Здравствуйте, netch80, Вы писали:


N>Вычисления производятся с ним, но результаты могут округляться на каждой операции до одинарной или двойной точности. Этот режим рулится у MS через функции типа _control87

Не совсем. До заданной точности округляется не весь результат операции, а только его мантисса. И используя только fpu control word нельзя без дополнительных приседаний получить вычисления как в float или как в double из IEEE754.
То есть такая функция может и будет выдавать разный результат при вычислении через sse и через i387 вне зависимости от значения fpu control word:
float f(float m) {
  return m * 8.0f / 8.0f;
}

(например, если вызвать её с очевидным аргументом f(FLT_MAX); но и с малыми числами возникает аналогичная проблема).


Чтобы получить именно поведение float или double на i387, нужно дополнительно форсировать усечение и экспоненты числа, а не только мантиссы. Например gcc с опцией -ffloat-store умеет это делать через постоянную выгрузку значений в память, что влечёт за собой правильную обработку экспоненты, но, конечно, замедляет вычисления (но на i387 особо другого выбора нет, если нужно именно совместимые и предсказуемые вычисления в рамках IEEE754).
Re: представление вещественных чисел в Visual Studio
От: kov_serg Россия  
Дата: 01.07.20 20:04
Оценка: 6 (1) +1
Здравствуйте, sergey2b, Вы писали:

S>я раньше встречал упоминание, что CPU обрабатывает вещественные числе представленные в double

S>и при использовании float перед каждой операцией происходит преобразование типа числа

S>судя по этому документы это уже не так IEEE Floating-Point Representation


S>какой вещественный тип лучше использовать с точки зрения оптимизации по скорости


С точки зрения оптимизации по скорости следует всегда профилировать и всегда контролировать скорость (обычно throughput).
На практике разницу в размере данных кэш процессора сглаживает вполне себе успешно и вычисления что с float что с double выполняются примерно 99% с одинаковой скоростью, но бывают ньюансы.

ps: кстати при распаралеливании можно получать разные результаты так как (a+b)+c != a+(b+c)
Отредактировано 01.07.2020 20:08 kov_serg . Предыдущая версия . Еще …
Отредактировано 01.07.2020 20:05 kov_serg . Предыдущая версия .
Re[3]: представление вещественных чисел в Visual Studio
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.07.20 05:14
Оценка:
Здравствуйте, watchmaker, Вы писали:

N>>Вычисления производятся с ним, но результаты могут округляться на каждой операции до одинарной или двойной точности. Этот режим рулится у MS через функции типа _control87

W>Не совсем. До заданной точности округляется не весь результат операции, а только его мантисса.

Эээ
_порядок_ не может _округляться_, очевидно. Он может только усекаться.

Да, в то, что у промежуточного хранения шире диапазон порядков, я намеренно не стал углубляться.

(Тут можно было бы обсудить поведение денормализованных, но уже облом.)

W>float f(float m) {

W> return m * 8.0f / 8.0f;
W>}
W>(например, если вызвать её с очевидным аргументом f(FLT_MAX); но и с малыми числами возникает аналогичная проблема).

Всё верно, спасибо, но я посчитал это излишним для исходной темы.

W>Чтобы получить именно поведение float или double на i387, нужно дополнительно форсировать усечение и экспоненты числа, а не только мантиссы. Например gcc с опцией -ffloat-store умеет это делать через постоянную выгрузку значений в память, что влечёт за собой правильную обработку экспоненты, но, конечно, замедляет вычисления (но на i387 особо другого выбора нет, если нужно именно совместимые и предсказуемые вычисления в рамках IEEE754).


[q] Use '-ffloat-store' for such programs, after modifying them to store all pertinent intermediate computations into variables./[q]

ещё и сохранять в переменные все промежуточные значения даже какого-нибудь b*b-4*a*c... вывернуться применить такое, конечно, можно, но код будет ужасен. Не вижу большой пользы в этой опции.
The God is real, unless declared integer.
Re[3]: представление вещественных чисел в Visual Studio
От: LaptevVV Россия  
Дата: 02.07.20 07:15
Оценка:
S>>>судя по этому документы это уже не так IEEE Floating-Point Representation
LVV>>Студия здесь не при делах.
N>При делах.
ну, тогда, если уж быть ТОЧНЫМ — это все касается компилятора, а не студии...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: представление вещественных чисел в Visual Studio
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.07.20 11:55
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

S>>>>судя по этому документы это уже не так IEEE Floating-Point Representation

LVV>>>Студия здесь не при делах.
N>>При делах.
LVV>ну, тогда, если уж быть ТОЧНЫМ — это все касается компилятора, а не студии...

Её штатного компилятора, идущего по умолчанию и используемого подавляющим большинством пользователей.
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.