Quantcast
Channel: Последние публикации
Viewing all articles
Browse latest Browse all 20

“Хотели как лучше” или “Фортран и немного C: как найти ключ к оптимизации и профилировке”

$
0
0

Производительность… Многие (если не сказать все) разработчики стремятся получить хорошо оптимизированный код и используют для этого различные методики. Наиболее простой и доступный способ - флаги компилятора для оптимизации, коих совсем немало. Ввиду огромного количества различных опций, которые могут переопределять другие, нередко возникает путаница. Как итог - ваше приложение может оказаться неоптимизированным, и результаты вас неприятно удивят.


Хотел бы остановиться на наиболее интересных случаях, с которыми я столкнулся в последнее время.


Сказ о Фортране


Итак, начнём с используемых всеми, кто работал с компилятором компании Intel, флагов для оптимизации /Od, O1, O2, O3. В данном случае будем говорить о Фортране (Intel® Visual Fortran Composer XE) и Windows*.

Достаточно подключить флаг /O2, и мы получим весьма неплохую оптимизацию, а производительность приложения вырастет в разы. Что мы делаем дальше? Конечно, хотим «прогнать» наше приложение через VTune™ Amplifier и посмотреть, всё ли так хорошо.


Вот здесь и начинается самое интересное. Для того, чтобы использовать профилировщик, нужно скомпилировать наш код в Release-режиме с отладочной информацией, то есть подключить флаг /debug:full (для плюсового компилятора - /Zi). Подразумевается, что в Release-режиме наши бинарники будут оптимизированы, потому что по умолчанию должен быть установлен флаг /O2, но… на деле всё происходит несколько иначе. Именно для Фортрановского компилятора и среды разработки Visual Studio было придумано следующее - в настройках проекта (Project → Properties → Fortran → Optimization) появился уровень оптимизации «Maximize Speed». Обычно, он устанавливает флаг /O2 неявно. Что значит неявно? Попробую объяснить издалека.


Если перейти в командную строку (Project → Properties → Fortran → Command Line), можно увидеть все опции, которые подключены. Разработчики Фортрановского компилятора позаботились о нас и начиная с версии компилятора 12.0 стали предусмотрительно показывать только те опции, которые мы установили не по умолчанию, то есть поменяли сами. Весьма удобно - сразу понятно, что было изменено в дефолтных настройках проекта. Замечу ещё раз, речь идёт только о Фортрановском компиляторе, в С++ этого нет. Так вот, когда по умолчанию в Release режиме стоит опция «Maximize Speed», /O2 явно не прописывается в командной строке. Всё было бы хорошо, если бы не флаг /debug:full (подключается в Project → Properties → Fortran → Debugging → Debug Information Format). Его специфика в том, что он отключает оптимизацию, то есть делает уровень Od по умолчанию, если явно не добавлен другой уровень.


В обычной командной строке всё работает в соответствии с документацией - написали “ifort -/debug:full /O2”, и бинарники будут оптимизированы и с «дебажной» информацией, не написали явно /O2 - оптимизация будет отключена при компиляции опцией /debug.


В Visual Studio же возникает путаница. Мы поменяли режим на Release и ожидаем, что теперь наш код будет оптимизирован. Подключили /debug:full (мы же хотим сделать профилировку), и он автоматически, явно добавился в командную строку… а вот /O2 нет. Итог - наше приложение не будет оптимизировано, и VTune покажет не те результаты, которых мы ждём.


Что же делать? Нужно быть очень внимательным и явно подключать флаг /O2 в командную строку (Project → Properties → Fortran → Command Line → Additional Options).


Если говорить о С++, там оптимизация добавляется явно из VS и подобной путаницы не возникает. Тем не менее, следить за флагами /Zi (C++) и /debug нужно внимательно, особенно, если компиляция происходит через командную строку, и не забывать явно прописывать флаг оптимизации. Через VS, соответственно, ещё внимательнее.


Я бы предложил несколько изменить текущее поведение компилятора. Нужно, в первую очередь, обращать внимание на оптимизацию - если она включена (пусть даже и неявно), то другие флаги не должны её переопределять. Либо хотя бы выводить об этом соответствующее уведомление.


Немного о С/С++


Ещё один момент. Если мы будем рассматривать поведение С++ компилятора в Linux, возникнут похожие проблемы, особенно ярко выраженные при работе с VTune. Если подключить флаги -g -O2, будут линковаться дебажные версии библиотек (например, при работе с TBB), которые, понятное дело, не будут отличаться хорошей производительностью. Как решение - ручками прописывать нужные библиотеки через -L.


Надеюсь, в ближайшее время подобное поведение будет пересмотрено. По крайней мере, я прикладываю для этого свои усилия. А пока - «осведомлён - значит вооружён».



Viewing all articles
Browse latest Browse all 20

Trending Articles