Прежде всего, я не рекомендую использовать -ffast-math
по следующим причинам:
Было доказано, что производительность на самом деле деградирует когда используя этот параметр в большинстве (если не все). Итак, "fast math" есть нет на самом деле это быстро.
Эта опция нарушает строгий IEEE соответствие с плавающей точкой операций, которые в конечном итоге приводит к накоплению вычислительных ошибок непредсказуемого характера.
Вы можете получить разные результаты в разных условиях, и разница может быть . Термин «среда» (в данном случае) подразумевает комбинацию: аппаратного обеспечения, ОС, компилятор. Это означает, что разнообразие ситуаций, когда вы можете получить неожиданные результаты, имеет экспоненциальный рост.
Другого печальное следствием является то, что программы, которые связывают против библиотеки, построенной с помощью этой опции могут ожидать правильную (IEEE-совместимый) с плавающей точкой математики, и это , где их ожидание сломаться, но это будет очень трудно рисунок вне почему.
Наконец, взгляните на this article.
По тем же причинам следует избегать -Ofast
(как она включает в себя зло -ffast-math
). Экстракт:
-Ofast
Игнорирование строгое соблюдение стандартов. -Ofast
позволяет оптимизировать все -O3
. Он также позволяет оптимизировать, которые недействительны для всех стандартных программ. Включается -ffast-math
и Fortran-specific -fno-protect-parens
и -fstack-arrays
.
Флаг такого типа, как -O4
. По крайней мере, я не знаю об этом, и в официальной документации GCC нет никаких следов. Таким образом, максимум в этом отношении - -O3
, и вы должны определенно использовать его, а не только для оптимизации математики, но и для сборки релизов в целом.
-funroll-loops
- очень хороший выбор для математических процедур, особенно с использованием векторных/матричных операций, где размер цикла может быть выведен во время компиляции (и в результате разворачивается компилятором).
Я могу порекомендовать еще 2 флага: -march=native
и -mfpmath=sse
. Аналогично -O3
, -march=native
хорош в целом для выпуска сборок любого программного обеспечения, а не только для интенсивной математики. -mfpmath=sse
позволяет использовать регистры XMM в инструкциях с плавающей запятой (вместо стека в x87 mode).
Кроме того, я хотел бы сказать, что жаль, что вы не хотите изменять свой код, чтобы получить лучшую производительность, поскольку это основной источник ускорения для векторных/матричных подпрограмм. Благодаря SIMD, SSE Intrinsics и Vectorization код тяжелой линейной алгебры может быть на порядок быстрее, чем без них. Тем не менее, правильное применение этих методов требует глубокого знания их внутренних компонентов и довольно много времени/усилий, чтобы изменить (фактически переписать) код.
Тем не менее, существует один вариант, который может быть подходящим для вашего случая. GCC предлагает auto-vectorization, который может быть включен по номеру -ftree-vectorize
, но он не нужен, поскольку вы используете -O3
(потому что он включает в себя -ftree-vectorize
). Дело в том, что вы все равно должны помочь GCC немного понять, какой код можно авто-векторизовать. Модификации обычно незначительны (при необходимости вообще), но вы должны быть знакомы с ними. См. Раздел Vectorizable Loops по ссылке выше.
Наконец, я рекомендую вам ознакомиться с библиотекой на основе шаблонов на C++, которая имеет высокоэффективную реализацию наиболее распространенных подпрограмм линейной алгебры Eigen. Он использует все техники, упомянутые здесь до сих пор очень умным способом. Интерфейс является чисто объектно-ориентированным, опрятным и приятным в использовании. Объектно-ориентированный подход очень важен для линейной алгебры, поскольку он обычно манипулирует чистыми объектами, такими как матрицы, векторы, кватернионы, вращения, фильтры и т. Д. В результате при программировании с Eigen вам никогда не придется самостоятельно разбираться с такими концепциями низкого уровня (как SSE, Vectorization и т. Д.), А просто наслаждаться решением вашей конкретной проблемы.
Я определенно рекомендую вам использовать Eigen. Это очень легко узнать. И хотя это сообщение касается многих обычных подозреваемых, которые нужно учитывать при оптимизации, Eigen идет намного дальше и делает много очень продвинутых вещей. –
Спасибо! Это очень помогло. Я действительно пытаюсь сравнить лучшее ускорение, которое дает оптимизированный компилятор код (это мой вопрос) с моим оптимизированным вручную кодом для операций с матрицами. – laxy
@ Харооган: спасибо за этот совет. Я полностью принимаю ваш ответ :). Мне жаль, что я еще не могу продвинуться. – laxy