У нас есть большое решение в Visual Studio 2010, которое включает в себя Fortran exe и несколько проектов статической библиотеки Fortran и C ++:
FORTRAN EXE --> MY_LIB (C++)
--> MY_LIB_2 (C++)
--> MY_LIB_3 (Fortran)
Мы и столкнулись с проблемой снижения производительности EXE-файла во время выполнения примерно на 50% после изменения зависимости статической библиотеки C ++.
Все работало нормально, пока мы не обратились к некоторым дополнительным заголовочным файлам в одной из библиотек C ++. Эти заголовки содержатся в проекте, который не содержит никаких исходных файлов, только заголовочные файлы C ++, и поэтому не производит никаких собственных скомпилированных выходных данных:
FORTRAN EXE --> MY_LIB (C++, now includes headers from headers-only project)
--> MY_LIB_2 (C++)
--> MY_LIB_3 (Fortran)
Причина того, что аспект, связанный только с заголовками, имеет большое значение, заключается в том, что невозможно задать оптимизации для проекта C ++ в свойствах проекта, если он не содержит исходный код (файлы .c / .cpp) и не выводит какой-либо вывод. Однако, когда они включены в другом месте, заголовки будут подвергаться той же оптимизации, что и включающий проект. Мы не делаем в коде ничего, что отключает оптимизацию (например, с помощью прагм).
После изменения наш код теперь работает примерно на 50% медленнее. В только что включенных заголовках мы вызываем только одну функцию, которая несет небольшие издержки и не учитывает замедление. Профилирование в AQTime показывает, что замедление согласованно во всем коде.
Я считаю, что причиной может быть непреднамеренное отключение оптимизаций. В момент соединения Fortran EXE мы получаем большое количество предупреждений C4748 об отключениях оптимизации в различных функциях, определенных во вновь включенных заголовках, а также в других файлах cpp, которые также включают их (мы не получили это перед включением дополнительных заголовков):
------ Build started: Project: FortranEXEProject, Configuration: Release Win32 ------
Linking...
Creating library D:\Source\Release\FortranEXEProject.lib and object D:\Source\Release\FortranEXEProject.exp
Generating code
c:\program files (x86)\microsoft visual studio 10.0\vc\include\memory(620) : warning C4748: /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function
d:\Source\CPPHeaderLibrary\header1.hpp(3231) : warning C4748: /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function
d:\Source\CPPSourceLibrary\source.cpp(54) : warning C4748: /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function
Во всех проектах включена оптимизация и используется генерация кода времени соединения (/ LTCG).
Обозреватель процессов обнаруживает, что линкер Fortran XLink.exe вызывает линкер C ++ LINK.exe.
Может кто-нибудь объяснить, что здесь происходит, и как обеспечить оптимизацию связанного кода C ++ в Fortran?
Мы используем Intel Fortran Composer XE 2011.
Заранее спасибо.
В конце мы заметили, что оптимизация была отключена в нескольких наших проектах статической библиотеки C ++ ниже по графу вызовов, который включал новые заголовки. Это произошло за некоторое время до добавления новых заголовков, но очевидно, что снижение производительности выявилось только тогда, когда новый код был связан. Повторное включение оптимизаций устранило проблему; что нас отвлекло, так это то, что XLINK вызывал LINK.EXE — получается, что link.exe — это просто линкер Windows — он не специфичен для C ++.
Других решений пока нет …