Size: a a a

Rust — русскоговорящее сообществo

2020 December 06

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Я почему-то считал, что современные компиляторы умеют хорошо оптимизировать математические выражения. Например в таком выражении:
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 считает независимо.
Это компилятор пока не дорос, или тут есть какие-то подводные камни из-за которых выбирается такое не оптимальное решение?
источник

SS

Slava Sokolovsky in Rust — русскоговорящее сообществo
Kirill (Cykooz) Kuzminykh
Я почему-то считал, что современные компиляторы умеют хорошо оптимизировать математические выражения. Например в таком выражении:
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 считает независимо.
Это компилятор пока не дорос, или тут есть какие-то подводные камни из-за которых выбирается такое не оптимальное решение?
Я думаю, что это проблема (или не проблема) ллвм, а не раста
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
Kirill (Cykooz) Kuzminykh
Я почему-то считал, что современные компиляторы умеют хорошо оптимизировать математические выражения. Например в таком выражении:
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, например.
Или просто недостаточно умный компилятор, да.
источник

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Приходится явно самому выполнять оптимизацию и писать вот так в коде:
x2 = x.powi(2);
9.0 * x2 * x - 15.0 * x2
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
Kirill (Cykooz) Kuzminykh
Приходится явно самому выполнять оптимизацию и писать вот так в коде:
x2 = x.powi(2);
9.0 * x2 * x - 15.0 * x2
А какой ассемблерный код выдаёт твоя версия?
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
Может, там получается доступ в память?
источник

МП

Максим Петров... in Rust — русскоговорящее сообществo
Kirill (Cykooz) Kuzminykh
Я почему-то считал, что современные компиляторы умеют хорошо оптимизировать математические выражения. Например в таком выражении:
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 считает независимо.
Это компилятор пока не дорос, или тут есть какие-то подводные камни из-за которых выбирается такое не оптимальное решение?
Можно вручную записать куб и квадрат через умножения и посмотреть, изменится ли сгенерированный код. Может тут именно вызов powi все ломает
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
Kirill (Cykooz) Kuzminykh
Я почему-то считал, что современные компиляторы умеют хорошо оптимизировать математические выражения. Например в таком выражении:
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 считает независимо.
Это компилятор пока не дорос, или тут есть какие-то подводные камни из-за которых выбирается такое не оптимальное решение?
https://godbolt.org/z/zn496h
Вообще я вижу 4 умножения в обоих случаях
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
Причём в «вручную оптимизированной» версии есть лишний movsd, так что компилятор справился лучше без этого
источник

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Хм, на самом деле у меня сама функция немного сложнее. Указанное выражение вычисляется внутри неё в одной из веток if-else. Но я сейчас проверю ваш вариант
источник

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Ага, у меня вот такой вариант даёт 5 умножений без ручной "оптимизации":
pub fn calc(x: f32) -> f32 {
   let a = x.abs();
   9.0 * a.powi(3) - 15.0 * a.powi(2)
}
Если убрать .abs() то будет 4 умножения
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
Возможно, LLVM по какой-то причине предпочитает делать лишний mulsd, чем лишний movsd? Хотя интуитивно mov должен быть дешевле.
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
Где-то внутри LLVM наверняка есть таблица стоимости инструкций, но я ХЗ как её сходу найти
источник

MK

Matwey Kornilov in Rust — русскоговорящее сообществo
Где-то была картинка со стоимостью инструкция на x86
источник

MK

Matwey Kornilov in Rust — русскоговорящее сообществo
В телеге туда-сюда репостилась
источник

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
А вот так вообще даёт 3 умножения:
pub fn calc_opt(x: f32) -> f32 {
   let a = x.abs();
   a.powi(2) * (9.0 * a - 15.0)
}
Но тут уж я не сильно ожидаю от компилятора, что он сможет сделать такой "вынос за скобки".
источник

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Emmanuel Goldstein
Возможно, LLVM по какой-то причине предпочитает делать лишний mulsd, чем лишний movsd? Хотя интуитивно mov должен быть дешевле.
Хм, если бы он был такой "умный", то зачем бы "повёлся" на мою простейшую оптимизацию и не превратил её в свой вариант с 5-ю умножениями вместо movsd?
источник

A

Apachee in Rust — русскоговорящее сообществo
Я правильно понимаю, что в https://docs.rs/tokio-postgres/0.6.0/tokio_postgres/ нету тредпула?
источник

A

Apachee in Rust — русскоговорящее сообществo
Не посоветуете асинхронную либу для PostgreSQL с тредпулом?
источник

A

Apachee in Rust — русскоговорящее сообществo
Ну или какую либу добавить, чтобы свой тредпул для этого создать
источник