выражения. Например в таком выражении:
9.0 * x.powi(3) - 15.0 * x.powi(2)
достаточно выполнить 4 умножения:
x2 = x * x;
x3 = x2 * x;
9.0 * x3 - 15.0 * x2
Но я удивился когда увидел, что в Rust это выполняется в 5 умножений - он куб и квадрат от x считает независимо.
Это компилятор пока не дорос, или тут есть какие-то подводные камни из-за которых выбирается такое не оптимальное решение?
Может, что-то с IEEE 754? Я не уверен, что должно получиться, если x2 это Infinity или NaN, например. Или просто недостаточно умный компилятор, да.
Я думаю, что это проблема (или не проблема) ллвм, а не раста
Можно вручную записать куб и квадрат через умножения и посмотреть, изменится ли сгенерированный код. Может тут именно вызов powi все ломает
https://godbolt.org/z/zn496h Вообще я вижу 4 умножения в обоих случаях
Хм, на самом деле у меня сама функция немного сложнее. Указанное выражение вычисляется внутри неё в одной из веток if-else. Но я сейчас проверю ваш вариант
Ага, у меня вот такой вариант даёт 5 умножений без ручной "оптимизации": pub fn calc(x: f32) -> f32 { let a = x.abs(); 9.0 * a.powi(3) - 15.0 * a.powi(2) } Если убрать .abs() то будет 4 умножения
плюсую догадки, что вопрос в семантике флоатов. скорее всего, ты хочешь аналог -ffast-math https://github.com/rust-lang/rust/issues/21690
Потому что в флоатах результат может отличаться, кроме случаев когда переменая одна
Но таки да, https://godbolt.org/z/esMvKh
Обсуждают сегодня