Почему запуск приложения в Linux медленнее при использовании общих библиотек? - PullRequest
1 голос
/ 11 сентября 2009

На встроенном устройстве, над которым я работаю, время запуска является важной проблемой. Целое приложение состоит из нескольких исполняемых файлов, которые используют набор библиотек. Поскольку пространство во флэш-памяти ограничено, мы хотели бы использовать разделяемые библиотеки.

Приложение работает как обычно, когда компилируется и связывается с общими библиотеками, и объем флэш-памяти уменьшается, как и ожидалось. Разница с версией, которая связана со статическими библиотеками, заключается в том, что время запуска приложения примерно на 20 секунд больше, и я понятия не имею, почему.

Приложение работает на процессоре ARM9 с частотой 180 МГц в ОС Linux 2.6.17, FLASH 16 МБ (файловая система JFFS) и 32 МБ ОЗУ.

Ответы [ 6 ]

7 голосов
/ 11 сентября 2009

Bacause совместно используемые библиотеки должны быть связаны во время выполнения, обычно с помощью dlopen () или что-то подобное. Для статических библиотек такого шага нет.

Редактировать: более подробно. dlopen должен выполнить следующие задачи.

  • Найти общую библиотеку
  • Загрузить его в память
  • Рекурсивно загрузить все зависимости (и их зависимости ....)
  • Разрешить все символы

Для этого требуется довольно много операций ввода-вывода.

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

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

4 голосов
/ 11 сентября 2009

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

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

OR

У вас могут быть общие библиотеки, которые занимают меньше места, но загружают больше времени.

Так что решите, чем вы хотите пожертвовать.

Есть много факторов для этой разницы (ОС, компилятор e.t.c), но хороший список причин можно найти здесь . По сути, общие библиотеки были созданы по космическим причинам, и большая часть «магии», задействованной для их работы, наносит удар по производительности.

(Историческая справка: оригинальный навигатор Netscape в Linux / Unix представлял собой статически связанный большой толстый исполняемый файл).

2 голосов
/ 22 октября 2009

Это может помочь другим с подобными проблемами:

Причина, по которой запуск в моем случае занял так много времени, заключалась в том, что настройка GCC по умолчанию - экспортировать все символы внутри библиотеки. Большим улучшением является установка параметра компилятора "-fvisibility = hidden".

Все символы, которые должна экспортировать библиотека, должны быть дополнены оператором

__attribute__ ((visibility("default")))

см. gcc wiki
и очень хорошая статья как писать разделяемые библиотеки

1 голос
/ 11 сентября 2009

Хорошо, теперь я узнал, что использование разделяемых библиотек имеет свои недостатки в отношении скорости. Я нашел эту статью о динамическом связывании и загрузке просветления. Процесс загрузки, кажется, намного дольше, чем я ожидал.

0 голосов
/ 12 сентября 2009

Один вариант, который мне кажется очевидным, - это статически связать несколько программ в один двоичный файл. Таким образом, вы продолжите делиться как можно большим количеством кода (возможно, больше, чем раньше), но вы также избежите накладных расходов динамического компоновщика и сэкономите место на наличии динамического компоновщика в системе.

Довольно легко объединить несколько исполняемых файлов в один, обычно вы просто проверяете argv и решаете, какую подпрограмму вызывать, основываясь на этом.

0 голосов
/ 11 сентября 2009

Интересно .. обычно время загрузки общей библиотеки незаметно в толстом приложении, которое статически связано. Поэтому я могу только предположить, что система либо очень медленно загружает библиотеку из флэш-памяти, либо загруженная библиотека проверяется каким-либо образом (например, приложения .NET запускают контрольную сумму для всех загруженных библиотек, значительно сокращая время запуска в некоторые случаи). Возможно, что совместно используемые библиотеки загружаются по мере необходимости и выгружаются впоследствии, что может указывать на проблему конфигурации.

Итак, извините, я не могу не сказать почему, но я думаю, что это проблема с вашим устройством / ОС ARM. Вы пробовали вводить код запуска или статически связываться с 1 из наиболее часто используемых библиотек, чтобы увидеть, имеет ли это большое значение. Также поместите совместно используемые библиотеки в тот же каталог, что и приложение, чтобы сократить время, необходимое для поиска в ФС библиотеки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...