Могут ли массивные вложенные циклы заставлять компоновщик работать бесконечно при компиляции в режиме Release?

Я компилирую очень маленькое приложение командной строки Win32 в режиме Release-Mode VS2010, при этом включена оптимизация скорости (не оптимизация памяти).

Это приложение предназначено для одной цели - выполнить одну предварительно определенную сложную математическую операцию, чтобы найти комплексное решение конкретной проблемы. Алгоритм полностью функциональный (подтвержден), и он компилируется и работает отлично в режиме Debug. Однако, когда я компилирую в Release-Mode (алгоритм достаточно велик, чтобы использовать оптимизацию), Link.exe работает бесконечно, а код никогда не заканчивает связывание. Он сидит при 100% использовании ЦП без изменений в использовании памяти (43,232 К).

Мое приложение содержит только два класса, оба из которых являются довольно короткими файлами кода. Однако алгоритм содержит 20 или около того вложенных циклов с встроенными вызовами функций изнутри каждого уровня. Является ли компоновщик попыткой запускать любой возможный путь через эти циклы? И если да, то почему у компоновщика Debug-Mode нет проблем?

Это крошечное приложение командной строки (2KB exe файл), и компиляция не должна занимать больше пары минут. Я дождался 30 минут, без изменений. Я подумываю о том, чтобы связать его в одночасье, но если он действительно пытается пропустить все возможные пути кода в алгоритме, он может в конечном итоге соединить десятилетия без суперкомпьютера.

Что мне нужно сделать, чтобы вытащить компоновщик из этого бесконечного цикла? Возможно ли, чтобы такой код создавал бесконечный цикл ссылок без получения ошибки компилятора до цикла ссылки?

EDIT:
Джерри Коффин указал, что я должен убить компоновщика и попытаться снова. Я забыл упомянуть об этом в исходном посте, но я прервал сборку, закрыл и снова открыл VS, и попытался построить несколько раз. Проблема последовательна, но я пока не изменил никаких вариантов компоновщика.
EDIT2:
Я также забыл упомянуть о том, что я удалил папки "Debug" и "Release" и перестроил с нуля. Те же результаты.
EDIT3:
Я только что подтвердил, что отключение функции inlining приводит к нормальной работе компоновщика. Проблема в том, что мне нужна функция вложения, так как это очень чувствительная к производительности операционная система с минимальным объемом памяти. Это приводит меня к тому, чтобы спросить, почему возникновение такой проблемы может возникнуть? " EDIT4:
Выход, который отображается во время бесконечного цикла ссылок:

Link:
  Generating code

EDIT5:
Я подтвердил, что размещение всего кода в одном файле CPP не решило проблему.

Ответы

Ответ 1

Вложенные циклы влияют только на компоновщик с точки зрения генерации кода времени ссылки. Там тонны опций, которые определяют, как это работает подробно.

Для начала я предлагаю отключить LTCG alltogether, чтобы увидеть, есть ли другая необычная проблема.

Если он отлично связывается с Release при отключенном LTCG, вы можете поэкспериментировать с ограничениями, внутренними характеристиками и уровнем оптимизации.

Ответ 2

Вы выполнили rebuild? Если один из объектных файлов поврежден или файл .ilk(хотя режим выпуска, вероятно, не использует его, я не могу быть уверен в настройках вашего проекта), то очищающий проход, который перестраивает, должен вылечить.

Закрытие и повторное открытие Visual Studio полезно только в тех случаях, когда отладка (или один из графических дизайнеров) поддерживает открытый дескриптор продукта сборки.

Что приводит к другому предложению - проверьте диспетчер задач и убедитесь, что у вас еще нет копии вашего приложения.

Ответ 3

Если компоновщик, похоже, является шеей бутылки, и оба класса довольно короткие, почему бы не поместить весь код в один файл? Кроме того, в диалоговом окне "Параметры проекта" есть опция многопроцессорной компиляции в визуальной студии под общей вкладкой С++. Оба эти могут помочь.

Ответ 4

Некоторые выбранные ответы:

Отладочные сборки не встроены. Не за что. Это позволяет помещать точки останова во все функции. Это wou

На самом деле не имеет значения, действительно ли компоновщик запускает бесконечный цикл, или же он оценивает 2 ^ 20 различных комбинаций inline/not inline. Последний может занять 2 ^ 20 секунд. (Мы знаем, что компоновщик встраивается из сообщения "Генерирующий код" ).

Почему вы все равно используете LTCG? Для такого небольшого проекта вполне возможно разместить все в одном файле .cpp. В настоящее время компилятор просто анализирует С++ и не генерирует никакого кода. Это также объясняет, почему у него нет никаких проблем: в компиляторе всего один цикл, по всем строкам исходного кода.

Ответ 5

Здесь в моей компании мы обнаружили нечто подобное.

Насколько я знаю, это не бесконечный цикл, просто очень длительная операция.

Это означает, что у вас есть параметры:

  • отключить оптимизацию
  • Дождитесь окончания компоновщика

Вы должны решить, действительно ли вам нужны эти оптимизации. Здесь программа - это всего лишь небольшой помощник, где не имеет значения, работает ли программа 23,4 секунды или 26,8. Увеличение скорости программы по сравнению со скоростью сборки делает оптимизацию практически бесполезной. По крайней мере, в нашем специальном сценарии.

Ответ 6

Я столкнулся именно с этой проблемой, пытаясь создать OSMesa x64 Release mode. Мой вклад в эту дискуссию состоит в том, что после того, как компоновщик запустил всю ночь, он действительно выполнил правильную работу.