amarao: (Default)
amarao ([personal profile] amarao) wrote2021-02-16 12:57 pm

СЯУ про оптимизации floating-point

После невероятно плодотворного срача на хабре, обнаружилось что:
1. fdiv очень медленный. Даже в конвейере он медленнее умножения (+71.244%).
2. Rust (LLVM?) оптимизирует деление на 2.0 заменой его на умножение на 0.5. Применимо ко всем положительным степеням двойки (вплоть до 2u128 << 126).
3. Деление на 0.5 вообще превращается в сложение. (А вот оптимизации умножения на ноль в цикле не происходит - честные 10 умножений на ноль).
4. criterion, как всегда, на высоте. black_box отлично работает: a = black_box(b/black_box(2.0)) отключает все оптимизации.
5. Интереснейший сайт https://godbolt.org/

И я не знаю как его работу воспроизвести руками (посмотреть дизассемблер для кода конкретной функции в rust). Я это себе в качестве домашнего задания по lore оставлю.

PS. Я медленно переползаю на dreamwidth, но без фанфар. Кому удобно ЖЖ, будет жж.
sab123: (Default)

[personal profile] sab123 2021-02-17 05:48 am (UTC)(link)
Вообще любое деление на плавающую константу превращается нынешними компиляторами в умножение на обратное. Еще интереснее то, что и в железе в наши дни деление ускоряется тем же самым способом - как сочетание вычисления обратного и умножения. Хм, не помню какую я недавнюю систему команд смотрел пару лет назад, RISC V, что-ли, так там операции деления вообще нет, только вычисление обратного.

А то, что деление гораздо медленне умножения - давно известно. Целочисленное умножение еще 25 лет назад делалось за один такт в RISC процессорах, с той же скоростью что и сложение.