Как определить самый быстрый порядок ссылок?
У меня около 50 различных статических библиотек, связанных с моим проектом на С++, и связь занимает в среднем 70 секунд.
Я обнаружил, что на этот раз перемещение с порядком ссылок библиотек изменится. Ожидается, что я думаю, что если компоновщику не нужно искать набор символов по всей таблице символов, которые он создал до этой точки.
Я предполагаю, что могу использовать "nm", чтобы получить график зависимости между статическими библиотеками. Однако это даст мне только один "правильный" порядок ссылок. Каковы были бы факторы, связанные с получением самого быстрого порядка ссылок?
У меня возникает ощущение, что это будет связано с вышеупомянутым графиком зависимостей, получив обход, который попытается свести к минимуму некоторое количество, но я действительно не уверен, что.
Любая помощь будет оценена по достоинству.
Я в основном использую компилятор Intel, а также компилятор gcc время от времени. Оба они, кажется, используют GNU ld-компоновщик, когда я проверяю его сверху. Надеюсь, это поможет...
Поэтому, чтобы немного разъяснить, что я пытаюсь спросить, я уже знаю, как получить 1-проходное упорядочение из набора статических библиотек. Я написал этот script сам, но, как говорит Олаф ниже, есть хорошо известные инструменты для этого.
Мой вопрос в том, что у меня уже есть два порядка 1-проходных ссылок, один из которых работает в ~ 85, а другой - в ~ 70 секунд. Настолько ясно, что еще есть оптимизация, которую мы можем сделать в рамках 1-го порядка.
Ответы
Ответ 1
В качестве альтернативы, почему бы не попробовать компилировать ваши библиотеки для общих библиотек, а не для статических библиотек?
Где я работаю, один крупный проект связывает время около 6 минут, это было только для 5 библиотек!
Мое решение было (для отладочной версии), создавать файлы .so в алфавитном порядке (libA.so, libB.so и т.д.), поэтому каждая отдельная ссылка была не слишком длинной, а конечная ссылка была намного короче, потому что все ( частичная) ссылка была сделана ранее. Версия выпуска была построена по-старому, потому что с моим новым методом была воспринята "опасность".
Мне удалось получить 1 модуль компиляции/ссылки с 6 минут до 10 секунд с помощью этого метода.
Ответ 2
В прошлом порядок объектов в статической библиотеке был важен. Вы можете сортировать объекты соответственно с помощью:
$lorder *.o | tsort
Возможно, вы могли бы сделать то же самое с вашими основными объектами и библиотеками, например. lorder main.o test.o libsome.a libthing.a | tsort
. Посмотрите man lorder
Ответ 3
На основе информации сравнивая ld с золотом, скорость ld зависит от того, насколько велика таблица символов. По мере того, как таблица символов растет из обработки объектных файлов, медленнее становится шаг ссылки. Таким образом, если у вас есть два разных 1-го порядка связывания, то тот, который помещает библиотеки с большим количеством символов в исправление позже в этом порядке, должен быстрее связываться. Вы должны иметь возможность модифицировать топологическую сортировку, чтобы включить количество символов в критерии упорядочения.
Ответ 4
Вы говорите об однопроходном заказе, основанном на порядке объектов и библиотек, но если он ищет статическую библиотеку, он не может гарантировать, что что-либо в статической библиотеке будет в любом конкретном порядке, и на самом деле вы можете только контролируйте это, заказывая статическую библиотеку определенным образом, когда вы ar
его.
Кроме того, не понимая, как компоновщик использует статический либратор (y | ies), два наилучших предположения, которые могут быть сделаны, следующие:
- Он создает хеш-таблицу символов, которая ссылается на объекты (объекты), которые предоставляют или нуждаются в них; если это точное предположение, то лучшая нижняя граница, которую вы можете получить в статической библиотеке, - это время, необходимое для заполнения такой хэш-таблицы и чтения из нее.
- Он слепо читает из архива на основе порядка, указанного в индексе архива.
Как попытка найти нижнюю границу вашего оптимального времени ссылки, попробуйте связать все или подмножество объектов в архиве (архивах) как перемещаемый объект; для подмножества, если возможно, идентифицировать все объекты, на самом деле связанные.
Страница руководства для lorder
указывает, что вы можете получить те же результаты с помощью ar ts <archive>
..., который напечатает упорядоченный список для вас. На странице руководства для ar
показано, что запуск ar
с флагом s
автоматически сохранит этот оптимальный порядок в индексе архива.
Кроме того, имейте в виду, что потенциально могут быть циклические зависимости, хотя, если вы уже запутались в tsort
, об этом вам уже сообщили.
Наконец, я оставлю вас с последней информацией. То, что вы хотите, - это то, что может решить проблему NP-complete. Удачи.
Я выполнял некоторые временные тесты в последнее время для сборки, над которой я работаю; Я добавляю флаг s
в свой ARFLAGS
, чтобы увидеть, какой эффект он имеет.
В целом, похоже, увеличилось время сборки, но я считаю, что логическое объяснение почему:
- Большинство исполняемых файлов/общих объектов не используют статические ссылки
- Он создает PIC и не-PIC-версии каждой статической библиотеки
Если бы мы делали гораздо более тяжелое использование статических библиотек, мы, вероятно, увидели бы выгоду от этого.