Могут ли массивные вложенные циклы приводить к бесконечной работе компоновщика при компиляции в Release-Mode? - PullRequest
14 голосов
/ 28 февраля 2011

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

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

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

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

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

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

Link:
  Generating code

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

Ответы [ 6 ]

3 голосов
/ 28 февраля 2011

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

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

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

1 голос
/ 01 марта 2011

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

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

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

  1. отключить оптимизацию
  2. дождитесь окончания работы компоновщика

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

1 голос
/ 01 марта 2011

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

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

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

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

1 голос
/ 01 марта 2011

Если компоновщик кажется узким местом, и оба класса довольно короткие, почему бы не поместить весь код в один файл? Кроме того, в Visual Studio имеется опция компиляции с несколькими процессорами на вкладке «Общие» C ++ в диалоговом окне настроек проекта. И то, и другое может помочь.

1 голос
/ 28 февраля 2011

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

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

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

0 голосов
/ 04 мая 2012

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

...