Вопрос или проблема
Кто-нибудь использовал связыватель gold
раньше? Чтобы связать довольно большой проект, мне пришлось использовать его вместо GNU ld
, который выдал несколько ошибок и не смог связать.
Как связыватель gold
способен связывать большие проекты, где ld
терпит неудачу? Есть ли какая-то хитрость с памятью?
Связыватель gold
был разработан как ELF-специфический связыватель с целью создания более поддерживаемого и быстрого связывателя, чем BFD ld
(традиционный связыватель GNU binutils). Как побочный эффект, он действительно способен связывать очень большие программы, используя меньше памяти, чем BFD ld
, предположительно из-за меньшего количества уровней абстракции, а также потому, что структуры данных связывателя более непосредственно сопряжены с форматом ELF.
Я не уверен, что существует много документации, которая специально рассматривает различия в дизайне между двумя связывателями и их влияние на использование памяти. Существует очень интересная серия статей о связывателях от Иана Лэнса Тейлора, автора различных GNU связывателей, в которых объясняются многие проектные решения, приведшие к gold
. Он пишет, что
Связыватель, над которым я сейчас работаю, называется gold; это мой третий связыватель. Он исключительно ELF связыватель. Цель снова заключается в скорости, в данном случае быстрее, чем мой второй связыватель. Этот связыватель был значительно замедлен за годы добавлением поддержки ELF и разделяемых библиотек. Эта поддержка была добавлена в виде патчей, а не изначально разработана.
(Второй связыватель — это BFD ld
.)
Связыватель gold
объявлен устаревшим в binutils 2.44 и в будущем будет полностью удалён.
Связыватель gold был написан, чтобы сделать процесс связывания значительно быстрее. По словам автора gold Иана Лэнса Тейлора
На данный момент у gold есть только одно значительное преимущество перед существующим связывателем: он быстрее. На больших C++ программах я измерил, что он работает в пять раз быстрее.
Он сравнивает производительность связывателя gold с традиционным GNU связывателем. gold (в отличие от GNU связывателя) не использует библиотеку BFD для обработки объектных файлов.
Недостаток gold в том, что (в отличие от GNU связывателя, который может обрабатывать множество типов объектных файлов) он может связывать только объектные файлы формата ELF.
Что касается проблем, с которыми вы столкнулись при использовании GNU связывателя, вот интересный ответ на похожий вопрос на Stack Overflow от Майкла Адама:
Связыватель gold даже нашёл некоторые проблемы с зависимостями в нашем коде, поскольку он, кажется, более корректен, чем классический связыватель с точки зрения некоторых деталей. Смотрите, например, этот коммит Samba.
Бенчмарк gold
против ld
Я опубликовал конкретный синтетический бенчмарк ld
vs gold
на https://stackoverflow.com/questions/3476093/replacing-ld-with-gold-any-experience/53921263#53921263
Результаты в кратце: gold был в 2-3 раза быстрее, чем ld на GCC 9.3.0, binutils 2.34.
Это увеличение скорости может значительно изменить ситуацию в сложных проектах на C++ с неуправляемыми шаблонами и генерацией кода, поскольку шаг связывания включает все файлы проекта и, в отличие от компиляции, должен выполняться всегда, даже если вы измените только один .cpp файл.
Так что медленное время связывания делает цикл разработки невыносимым и, вероятно, является основной причиной, по которой Google вложил в это ресурсы. Только представьте, какие преимущества связаны с ожиданием 10 секунд вместо 30 секунд для каждого незначительного изменения файла.
Ускорение времени в синтетическом бенчмарке также согласуется с фактическим увеличением, которое я получил на сложном реальном проекте (gem5), как упомянуто в том ответе.
На современных системах GNU/Linux доступны три связывателя:
- ld, поддерживаемый GNU binutils,
- gold, поддерживаемый GNU binutils, “все еще в бета-тестировании”,
- lld, разработанный как часть проекта LLVM.
Для тестов скорости смотрите: https://www.phoronix.com/scan.php?page=article&item=lld4-linux-tests&num=2 Вкратце, lld
самый быстрый, за ним следует gold
, а затем ld
Некоторые источники утверждают, что проект gold стагнирует, и структура пакетов в Fedora это отражает.
.
Ответ или решение
Золотой компоновщик, известный как “gold”, представляет собой инструмент для связывания в программировании, который был разработан для улучшения скорости процесса компоновки по сравнению с традиционным компоновщиком GNU BFD, также известным как “ld”. Ниже рассмотрим его основные теоретические особенности, приведем примеры и рассмотрим случаи применения.
### Теория
#### Архитектура и особенности
“Gold” был разработан как высокоэффективный компоновщик, работающий исключительно с форматом ELF (Executable and Linkable Format). Одной из основных целей было повышение скорости компоновки, что было достигнуто за счет отказа от использования библиотеки BFD, применяемой в традиционном GNU-компоновщике. Это позволило упростить внутренние структуры данных и наилучшим образом оптимизировать процесс обработки, что особенно важно для крупных проектов.
По словам Иана Лэнса Тейлора, автора “gold”, создание нового компоновщика было обусловлено необходимостью повысить скорость работы при обработке больших C++ программ. Как предполагается, “gold” может работать в несколько раз быстрее “ld”, за счет чего ускоряется общий цикл разработки, особенно при компиляции сложных проектов с большим количеством шаблонов и генерацией кода.
#### Ограничения и поддержка
Ограничением “gold” является его способность работать только с ELF-файлами, что может быть недостаточным в средах, где требуется поддержка множества форматов. Это фактически делает его менее универсальным, чем “ld”, который может обрабатывать различные типы объектных файлов. Кроме того, проект “gold” в последние годы стал менее активным и был объявлен устаревшим в binutils версии 2.44. Это означает, что в будущем его могут вовсе исключить из набора инструментов GNU.
### Пример
Предположим, у вас есть крупный проект на языке C++, где большое количество шаблонных классов приводит к значительному увеличению времени компоновки. Вы обнаружили, что стандартный GNU-компоновщик “ld” не справляется с задачей, выдавая ошибки из-за ограничений на объем памяти или ресурсов, необходимых для обработки проекта.
Используя “gold”, вы можете заметить значительное ускорение процесса и снижение использования памяти. Например, в синтетических тестах и на реальных проектах, таких как gem5, “gold” показал ускорение в два-три раза по сравнению с “ld”. Именно эта характеристика делает его ценным инструментом для разработчиков, работающих над сложными проектами.
### Применение
В каких случаях имеет смысл использовать “gold”? Основное преимущество “gold” в его быстрой обработке делает его пригодным выбором для разработчиков, работающих над крупными ПО проектами, особенно в средах где скорость компоновки критична для производительности.
Заменяя “ld” на “gold”, можно значительно сократить время полного цикла компиляции/компоновки, что особенно важно в больших корпоративных средах, например, в Google, которые активно использовали “gold” для повышения производительности работы своих систем.
При этом важным шагом будет тестирование вашего проекта с использованием “gold” для выявления возможных проблем с совместимостью и корректностью результатов компоновки. Кроме того, стоит всегда помнить о тенденциях в развитии инструментов, ведь “gold” может потерять поддержку в будущем, и нужно быть готовыми к переходу на альтернативные решения, такие как “lld” от проекта LLVM, который также демонстрирует впечатляющие результаты по скорости.
В подытоживании, “gold” представляет собой мощное средство для компоновки программ, когда приоритетом является скорость обработки и использование современных оптимизаций. Однако, следует учитывать его ограничения и тенденции в разработке инструментов, чтобы вовремя адаптироваться и использовать наиболее подходящие для вашей области инструменты.