2012-02-23 2 views
12

Прочитав тему, есть множество свидетельств из многочисленных источников, в которых использование стандартных C или C++-преобразований для конвертации с плавающей точкой в ​​целые числа на Intel очень медленно. Чтобы соответствовать спецификации ANSI/ISO, процессорам Intel необходимо выполнить большое количество инструкций, в том числе необходимых для переключения режима округления аппаратного обеспечения FPU.Как обеспечить, чтобы lrint был встроен в gcc?

Существует ряд обходных решений, описанных в различных документах, но самый чистый и самый портативный, по-видимому, является вызовом lrint(), добавленным в стандарты C99 и C++ 0x. Во многих документах говорится, что компилятор должен встроить эти функции в том случае, если оптимизация включена, что приводит к коду, который быстрее обычного, или вызову функции.

Я даже нашел ссылки на пакеты отслеживания функций gcc, чтобы добавить это встроенное расширение в gcc-оптимизатор, но в моих собственных тестах производительности мне не удалось заставить его работать. Все мои попытки показывают, что производительность lrint намного медленнее, чем простой стиль C или C++. Изучение сборки сборки компилятора и дизассемблирование скомпилированных объектов всегда показывает явный вызов внешней функции lrint() или lrintf().

Режимы gcc, с которыми я работал, - это 4.4.3 и 4.6.1, и я попытался выполнить ряд комбинаций флагов на 32-битных и 64-битных объектах x86, включая опции для явного включения SSE.

Как получить gcc для встроенного расширения lrint и дать мне быстрые преобразования?

+1

Вы действительно профилировали и подтвердили, что с использованием очевидного приведения значительная часть времени выполнения вашей программы? –

+2

Профилирование показывает, что я могу получить разницу в скорости 2-4%, используя ручной макет ассемблера, снятый с статьи. Это стоит того, что вычисление выполняется между кадрами приложения 3D-рендеринга. –

+1

Вы установили '-fno-math-errno'? вы также должны рассмотреть возможность использования '-ffast-math', что не всегда является опцией, если вы полагаетесь на определенную fp-семантику ... – Christoph

ответ

10

Функция lrint() может вызывать ошибки домена и диапазона. Одним из возможных способов использования libc такими ошибками является установка errno (см. Раздел 7.12.1 C99/C11). Накладные расходы на проверку ошибок могут быть весьма значительными, и в этом конкретном случае, как представляется, достаточно, чтобы оптимизатор принял решение против вложения.

Флаг gcc -fno-math-errno (который является частью -ffast-math) отключит эти проверки. Возможно, неплохо заглянуть в -ffast-math, если вы не полагаетесь на стандартизованную обработку семантики с плавающей запятой, в частности, NaN и бесконечности ...

0

Вы пробовали флаг -finline-functions в gcc.

Вы можете также прямой GCC, чтобы попытаться интегрировать все «простые достаточно» функции в своих абонентов с возможностью -finline-functions.

см http://gcc.gnu.org/onlinedocs/gcc/Inline.html

Здесь вы можете сказать НКУ, чтобы все функции встраивать, но не все будут включены. Компилятор использует некоторую эвристику, чтобы определить, достаточно ли эта функция достаточно, чтобы быть встроенной. Еще одна вещь заключается в том, что рекурсивная функция также не будет встроена здесь.

+0

Я попытался -finline-функции, и это не имело никакого значения для выхода компилятора. –

+0

, если вы используете lrint() математической библиотеки в своем коде и компилируете ее gcc, тогда lrint() не будет встроен, потому что в вашем случае это будет происходить из бинарной связанной библиотеки. код lrint() здесь не собирается –

+0

В этом документе указывается иначе: http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html «Функции ISO C99 ..... lrintf, lrintl, lrint ...... обрабатываются как встроенные функции, за исключением строгого режима ISO C90 (-ansi или -std = c90). " Далее в документе говорится: «Многие из этих функций оптимизированы только в определенных случаях, если они не оптимизированы в конкретном случае, вызывается вызов функции библиотеки». но я не смог разработать случай, в котором они оптимизированы. –