TGViewer
LinuxCamp | DevOps LinuxCamp | DevOps @linuxcamp_tg · 13.6K subscribers
Post #46 3.24K
Ускорение работы библиотек: отключение ленивого связывания

Как мы выяснили в прошлой публикации, ленивое связывание (Lazy Binding) - это процесс определения адресов символов на этапе выполнения. Данный механизм ускоряет загрузку приложения ценой накладных расходов в процессе работы: вместо прямого вызова функции вызывается PLT заглушка, которая задействует набор дополнительных машинных инструкций и дергает динамический компоновщик для определения адресов.

Система ленивого связывания не везде используется по дефолту: в Windows таблица адресов (Import Address Table - IAT) полностью заполняется на старте программы, в Linux ситуация обратная, однако никто не говорить, что скорректировать такое поведение невозможно - все возможно (особенно в Linux)!

Современные компиляторы поддерживают флаг "-fno-plt", который, как видно из названия, исключает из кода plt заглушки и необходим для связывания символов на старте программы:


$ gcc -fno-plt -o prog main.c


Использование данного флага:

1) уменьшает размер исполняемого файла: каждая заглушка добавляет, как минимум, 32 байта к объему (для x86/x86_64 архитектур)

2) уменьшает загруженность регистров и "instruction cache" для CPU

3) ускоряет вызовы библиотечных функций и, как следствие, процесс выполнения кода

По данным разработчика yugr, использование флага в clang дало +10% к приросту производительности для большого проекта (автор деталей не уточнял). Это действительно хороший и значимый результат, особенно, для высоконагруженных сервисов, где каждая микросекунда на счету.

Интересный факт: во многих дистрибутивах сборка пакетов выполнена с внедрением флага "-fno-plt". Некоторые утилиты, в качестве исключений, могут обходить стороной этот флаг при компиляции. Так, например, для xorg, glibc, valgrind, openjdk (внутри Arch Linux) он не используется.

Cуществует еще 2 способа отключить ленивое связывание: переменная окружения "LD_BIND_NOW" и флаг компоновщика "-z now". При таком подходе влияние оказывается на загрузчик, из-за чего может не получится выжать максимум из производительности, т.к. вызов функций все также будут происходить через plt заглушки:


$ LD_BIND_NOW=1 ./prog
$ gcc -o prog main.c -Wl,-z,now


Результат использования флага и переменной окружения аналогичен:

1) plt заглушки все еще являются частью кода

2) все адреса символов определяются на этапе запуска программы

3) не вызывается динамический компоновщик для связывания функций при первом использовании

4) при вызове функции, переход происходит сразу на конкретный адрес в таблице GOT

Таким образом, однозначно добиться дополнительной производительности от приложения можно через использование флага компилятора "-fno-plt", который исключит из бинарного файла все plt заглушки и приведет к вызову функций через прямое обращение к GOT.

#linux
  • 👍 16
  • 🔥 6
  • 👏 2
More from @linuxcamp_tg
  1. Oct 9, 2026🤖Обходим «белый список» вместе с STRELKA Думали, что белые списки не обходятся когда глуш…
  2. Sep 28, 2026Проекту GNU вчера исполнилось 43 года 1983 год: Ричард Столлман объявил планы разработать…
  3. Sep 25, 2026Linux будет работать на ноутах с Snapdragon X2. Qualcomm добавляет полноценную поддержку L…
  4. Sep 24, 2026Так все по делу)) Советует же самый быстрый фикс LinuxCamp | #memes
  5. Sep 23, 2026Планы на 3 октября — прийти на RWB Infra x Security Meetup Мы направим прожекторы на инфра…
  6. Sep 22, 2026Ещё одна рекордная неделя для AI-разработки в Linux. На прошлой неделе в ядро попало 1 634…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →