Почему флаг оптимизации (-O3) не ускоряет вычисления в четыре раза?

У меня есть высокоточный ODE (обыкновенные дифференциальные уравнения) решатель, написанный на C ++. Я делаю все вычисления с пользовательским типом real_type, Существует typedef, объявляющий этот тип в заголовке:

typedef long double real_type;

Я решил изменить длинный двойной тип на __float128 для большей точности. В дополнение к этому я включил quadmath.h и заменил все стандартные математические функции на те из libquadmath.

Если «длинная двойная» версия создается без каких-либо флагов оптимизации, некоторый эталонный ODE решается за 77 секунд. Если эта версия построена с флагом -O3, то же ODE решается за 25 секунд. Таким образом, флаг -O3 ускоряет вычисления в три раза.

Но в версии «__float 128», собранной без флагов, аналогичный ODE решается за 190 секунд, а с -O3 — за 160 секунд (разница ~ 15%). Почему оптимизация -O3 дает такой слабый эффект для вычислений с четверной точностью? Может быть, я должен использовать другие флаги компилятора или включить другие библиотеки?

1

Решение

Оптимизация компилятора работает следующим образом: компилятор распознает определенные шаблоны в вашем коде и заменяет их эквивалентными, но более быстрыми версиями. Не зная точно, как выглядит ваш код и какие оптимизации выполняет компилятор, мы не можем сказать, чего не хватает компилятору.

Вполне вероятно, что несколько оптимизаций, которые компилятор знает, как выполнить для собственных типов с плавающей запятой и их операций, он не знает, чтобы выполнить на __float128 и реализации библиотек операций. Он может не распознавать эти операции такими, какие они есть. Может быть, он не может смотреть на реализации библиотеки (вы должны попробовать скомпилировать библиотеку вместе с вашей программой и включить оптимизацию во время соединения).

2

Другие решения

Та же оптимизация обеспечила практически одинаковую выгоду. Процент снизился только потому, что сама математика заняла больше времени.

Чтобы полагать, что оптимизация должна составлять один и тот же процент, вы должны полагать, что если математика займет больше времени, оптимизатор найдет больше сбережений. Почему ты так думаешь?

0

Если ваша цель — архитектура x86, то в GCC __float128 является фактическим типом FP ​​четверной точности, в то время как long double это 96-битный тип FP x87 (расширенный дважды).

Разумно, что математика с типами меньшей точности может быть быстрее, чем математика с типами большей точности. Также разумно, что математика с нативными типами оборудования может быть быстрее, чем математика с неродными типами.

0
По вопросам рекламы [email protected]