Visual studio отключить оптимизацию кода
Is it possible to disable RVO (return value optimization) in Visual Studio 2010? Setting optimization flag to /Od (turns off all optimizations) doesn't help. In g++ there exists flag -fno-elide-constructors which disables RVO.
3 Answers 3
You cannot. It is just that simple. RVO/NRVO is Standard, and your code should not depend on it not being present.
As far as I can tell RVO/NRVO is not the Standard (see C++0x standard, section 12.8. Copying and moving class objects, paragraph 32). The Standard simply allows such optimization (g++ and VisualStudio implements it). I have no problem with that. But it would be nice to have some switch to disable it. For educational purposes maybe. Thank you, it's much clearer now :)
"If including it does not contradict the Standard, then it is Standard." I think it'd be more precise to say that "then it is allowed by the Standard.", and that does not necessarily mean that a compiler shouldn't provide a flag to turn it off. For instance I wanted to turn it off for educational purposes.
@Puppy The issue here - i.e. what the question is possibly asking, and what I arrived at the question looking for - is that you also cannot ever write code that assumes that it is included, because it is Standard-compliant to not include it. Hence, a compiler which provides and respects an option to disable it is Standard-compliant with or without the option enabled. If I want to write portable code, I may want to test my code both with and without it enabled, to ensure that it will work with all Standard-compliant compilers. This is easiest with a compiler-provided flag to disable it.
@JamieS That's the only presented motivation that actually makes some sense. I might comment that it's tricky to do this with testing because the exact situations where a compiler implements RVO and friends may differ between compilers or versions, so the preferable option is to simply not write objects that have impure copy/move constructors. That being said, you may have legacy code, etc, which does not do this correctly.
Оптимизируя исполняемый файл, можно добиться баланса между быстрым выполнением и небольшим размером кода. В этом разделе обсуждаются механизмы, предоставляемые Visual Studio для оптимизации кода.
Возможности языка
В следующих разделах описываются некоторые функции оптимизации в C/C++.
Прагмы и ключевые слова оптимизации
Список ключевых слов и прагм, которые можно использовать в коде для повышения производительности.
Параметры компилятора, упорядоченные по категориям
Список параметров компилятора /O, которые влияют на скорость выполнения или размер кода.
Декларатор ссылки rvalue: &&
Ссылки rvalue поддерживают реализацию семантики перемещения. Если для реализации библиотек шаблонов используется семантика перемещения, производительность приложений, использующих эти шаблоны, может значительно повыситься.
Прагма optimize
Если оптимизированный раздел кода вызывает ошибки или замедление, можно использовать прагму optimize, чтобы отключить оптимизацию для этого раздела.
Заключите код между двумя прагмами, как показано ниже:
Рекомендации по программированию
При компиляции кода с оптимизацией можно заметить дополнительные предупреждения. Такое поведение является ожидаемым, так как некоторые предупреждения относятся только к оптимизированному коду. Обращайте внимание на эти предупреждения, чтобы избежать многих проблем с оптимизацией.
Парадоксально, но оптимизация программы для ускорения может привести к снижению скорости выполнения кода. Это обусловлено тем, что некоторые оптимизации для скорости увеличивают размер кода. Например, функции встраивания устраняют издержки, вызванные вызовами функций. Однако встраивание слишком большого объема кода может сделать программу настолько большой, что число ошибок страниц виртуальной памяти увеличится. Таким образом, выигрыш в скорости, полученный при исключении вызовов функций, будет компенсирован обменом памятью.
В следующих разделах рассматриваются оптимальные методы программирования.
Рекомендации по оптимизации критичного по времени кода
Улучшенные методы программирования могут повысить производительность. В этом разделе предлагаются приемы программирования, которые помогут обеспечить удовлетворительную производительность критичного по времени кода.
Рекомендации по оптимизации
Общие рекомендации по эффективной оптимизации приложения.
Отладка оптимизированного кода
Поскольку оптимизация может изменить код, созданный компилятором, рекомендуется выполнить отладку приложения и оценить его производительность, а затем оптимизировать код.
В следующих разделах представлена информация о том, как отладить сборки выпуска.
В следующих разделах содержатся сведения о том, как оптимизировать сборку, загрузку и выполнение кода.
If you are trying to debug code, it is easier when that code is NOT optimized. When code is optimized, the compiler and runtime make changes to the emitted CPU code so that it runs faster, but has a less direct mapping to original source code. If the mapping is less direct, debuggers are frequently unable to tell you the value of local variables, and code stepping and breakpoints might not work as you expect.
For more info on JIT (Just In Time) debugging, read this documentation.
Normally the Release build configuration creates optimized code and the Debug build configuration does not. The Optimize MSBuild property controls whether the compiler is told to optimize code.
The 'Suppress JIT optimization on module load (Managed only)' option
To find the Suppress JIT optimization on module load (Managed only) option, select Tools > Options, and then select the General page under the Debugging node.
When should you check the 'Suppress JIT optimization' option?
Check this option when you downloaded the DLLs from another source, such as a nuget package, and you want to debug the code in this DLL. In order for suppression to work, you must also find the symbol (.pdb) file for this DLL.
If you are only interested in debugging the code you are building locally, it is best to leave this option unchecked, as, in some cases, enabling this option will significantly slow down debugging. There are two reasons for this slow down:
- Optimized code runs faster. If you are turning off optimizations for lots of code, the performance impact can add up.
- If you have Just My Code enabled, the debugger will not even try to load symbols for DLLs that are optimized. Finding symbols can take a long time.
Limitations of the 'Suppress JIT optimization' option
There are two situations where turning on this option will NOT work:
In situations where you are attaching the debugger to an already running process, this option will have no effect on modules that were already loaded at the time the debugger was attached.
Set "COMPlus_ReadyToRun": "0" by adding it to each profile in the Properties\launchSettings.json file:
Проще всего выполнять отладку кода, когда он НЕ оптимизирован. Когда код оптимизирован, компилятор и среда выполнения вносят изменения в выпущенный код ЦП, поэтому он выполняется быстрее, но имеет не такое прямое сопоставление с начальным исходным кодом. Если сопоставление менее прямое, отладчикам часто не удается определить значения локальных переменных и пошаговое выполнение кода и точки останова могут не работать должным образом.
Дополнительные сведения о JIT-отладке см. в этой документации.
Как правило, конфигурация сборки "Выпуск" создает оптимизированный код, а конфигурация сборки "Отладка" — нет. Свойство MSBuild Optimize определяет, нужно ли компилятору оптимизировать код.
Параметр "Отключать JIT-оптимизацию при загрузке модуля (только управляемый код)"
Чтобы найти параметр Отключать JIT-оптимизацию при загрузке модуля (только управляемый код) , щелкните Сервис > Параметры, а затем выберите страницу Общие в узле Отладка.
Когда следует включить параметр "Отключать JIT-оптимизацию"?
Установите этот флажок, если вы скачали библиотеки DLL из другого источника, например пакета NuGet, и хотите отладить код в этой библиотеке DLL. Чтобы отключение вступило в силу, необходимо также найти файл символов (PDB) для этой библиотеки DLL.
Если вас интересует отладка только локально создаваемого кода, лучше оставить этот флажок снятым, так как в некоторых случаях включение этого параметра значительно замедляет отладку. Для этого имеются две причины.
- Оптимизированный код выполняется быстрее. Если вы отключаете оптимизацию для большей части кода, это может повлиять на производительность.
- Если включен только пользовательский код, отладчик даже не будет пытаться загружать символы для оптимизированных DLL. Поиск символов может занять много времени.
Ограничения для использования параметра "Отключать JIT-оптимизацию"
Существует две ситуации, когда включение этого параметра НЕ работает.
В ситуациях, когда вы присоединяете отладчик к уже выполняющемуся процессу, этот параметр не влияет на модули, которые уже были загружены во время подключения отладчика.
Задайте "COMPlus_ReadyToRun": "0" , добавив его в каждый профиль в файле Properties\launchSettings.json:
У меня есть проект, использующий CMake, который не может скомпилировать этот код на VS 2015 из-за ошибки компилятора. (взаимодействие между разрешением шаблона, оптимизацией и обработкой исключений).
Этой ошибки можно избежать, отключив оптимизацию - хотя это дает неоптимальный код, по крайней мере, проект компилируется.
Как мне изменить уровень оптимизации по умолчанию для MSVC 2015 на /O0 в сборках Release и RelWithDebInfo ?
Моя наивная реализация была бы условной заменой в CMAKE_CXX_FLAGS - безопасно ли это в будущем?
3 ответа
Эта ошибка компилятора мешает компоновщику мусором, насколько я могу отследить проблему (VS2015 является новым, на момент написания этой статьи не было выпущено никаких патчей / обновлений). В компоновщике происходит сбой. Похоже, компилятор считает, что все прошло хорошо.
Когда эта ошибка «возбуждена», проблема заключается в коде, который использует сгенерированный объект шаблона. Другими словами, даже если вы отключите оптимизацию в заголовке, но снова включите оптимизацию в теле, это все равно приведет к сбою компоновщика. Что «работает», так это отключить оптимизацию кода, который создает экземпляры и использует функции-члены объекта шаблона (вы можете оставить оптимизацию для всего кода за пределами этой цели).
Например, в коде, опубликованном в вопросе, оставьте оптимизацию во всех заголовках. В функции, которая ИСПОЛЬЗУЕТ шаблон, выполните:
Это изолирует потерю оптимизации для того кода, который воспламеняет проблему, и компоновщик преуспевает.
Конечно, сами прагмы могут быть обернуты условными определениями или каким-либо другим механизмом, который вы можете отключить после выпуска патча для VS2015, который устраняет проблему.
Таким образом, код можно использовать, не беспокоясь о конфигурациях сборки (то есть, он будет работать как для сборки CMAKE, так и для сборки IDE) без необходимости обременять последующих пользователей кода (с чем-либо, кроме определения, чтобы контролировать, выполняется ли оптимизация. отключен).
Если это возможно в вашей ситуации, вы также можете попробовать что-то вроде:
Такой вид повторного написания кода позволяет обойти ошибку и компилировать без сбоя компоновщика.
Кроме того, это тоже обходит проблему:
Кроме того, что мне любопытно и представляет собой немного лучший дизайн (поскольку он не требует, чтобы один класс возился с членами другого)
Хорошая новость в том, что ЕСТЬ решение, которое не требует изменения правил сборки проекта, оставляет включенной оптимизацию и фактически идентично.
Похоже, что на самом деле виновником является предложение t.t1 = t.t2 = . . Почему такое назначение вызывает сбой компоновщика, а эквивалентные выражения в противном случае не являются загадкой для Microsoft, но на самом деле кажется, что решение приводит к немного лучшему виду кода.
Читайте также: