Pourquoi le démarrage d'une application sur Linux est-il plus lent lorsque vous utilisez des bibliothèques partagées?

StackOverflow https://stackoverflow.com/questions/1410691

  •  05-07-2019
  •  | 
  •  

Question

Sur le périphérique intégré sur lequel je travaille, le temps de démarrage est un problème important. L’ensemble de l’application se compose de plusieurs exécutables utilisant un ensemble de bibliothèques. L'espace dans la mémoire FLASH étant limité, nous aimerions utiliser des bibliothèques partagées.

L'application fonctionne normalement lorsqu'elle est compilée et liée à des bibliothèques partagées et la quantité de mémoire FLASH est réduite comme prévu. La différence par rapport à la version liée aux bibliothèques statiques est que le temps de démarrage de l’application est environ 20s plus long et je ne sais pas pourquoi.

L’application fonctionne sur un processeur ARM9 à 180 MHz avec Linux 2.6.17, 16 Mo FLASH (système de fichiers JFFS) et 32 ??Mo de RAM.

Était-ce utile?

La solution

Les bibliothèques partagées doivent être liées à l'exécution, généralement par dlopen () ou quelque chose de similaire. Il n’existe pas d’étape semblable pour les bibliothèques statiques.

Edit: quelques détails supplémentaires. dlopen doit effectuer les tâches suivantes:

  • Rechercher la bibliothèque partagée
  • Chargez-le en mémoire
  • Charge récursivement toutes les dépendances (et leurs dépendances ....)
  • Résoudre tous les symboles

Cela nécessite pas mal d'opérations d'E / S à accomplir.

Dans un programme lié de manière statique, tout ce qui précède est effectué à la compilation, pas à l'exécution. Par conséquent, il est beaucoup plus rapide de charger un programme lié de manière statique.

Dans votre cas, la différence est exagérée par le matériel relativement lent sur lequel votre code doit être exécuté.

Autres conseils

C’est un bel exemple du compromis classique entre vitesse et espace.

Vous pouvez lier statiquement tous vos exécutables pour qu'ils soient plus rapides, mais ils prendront plus de place

OU

Vous pouvez avoir des bibliothèques partagées qui prennent moins d’espace mais qui demandent plus de temps pour se charger.

Alors décidez ce que vous voulez sacrifier.

Plusieurs facteurs expliquent cette différence (système d’exploitation, compilateur, etc.), mais une bonne liste de raisons peut être trouvée ici . Des bibliothèques partagées ont été créées essentiellement pour des raisons d'espace et une grande partie de la "magie". impliqué pour les faire travailler prend un coup de performance.

(Comme note historique, le navigateur Netscape d’origine sur Linux / Unix était un exécutable gros fichier lié statiquement.)

Cela peut aider d'autres personnes ayant des problèmes similaires:

La raison pour laquelle le démarrage a pris si longtemps dans mon cas était que le paramètre par défaut du GCC était d'exporter tous les symboles à l'intérieur d'une bibliothèque. Une grosse amélioration consiste à définir un paramètre de compilation "-fvisibility = hidden".

Tous les symboles que la bibliothèque doit exporter doivent être complétés par l'instruction

__ attribut__ ((visibilité (" défaut ")))

voir wiki gcc
et le très bel article comment écrire des bibliothèques partagées

Ok, je viens d’apprendre que l’utilisation de bibliothèques partagées présente des inconvénients pour la vitesse. J'ai trouvé cet article sur les liens et chargement dynamiques . Le processus de chargement semble être beaucoup plus long que prévu.

Intéressant ... en général, le temps de chargement d'une bibliothèque partagée est imperceptible depuis une grosse application liée statiquement. Donc, je ne peux que supposer que le système est très lent pour charger une bibliothèque à partir de la mémoire flash, ou que la bibliothèque chargée est en cours de vérification (par exemple, les applications .NET exécutent une somme de contrôle pour toutes les dll chargées, ce qui réduit considérablement le temps de démarrage. certains cas). Il se peut que les bibliothèques partagées soient chargées selon les besoins, puis déchargées, ce qui pourrait indiquer un problème de configuration.

Donc, désolé, je ne peux pas m'empêcher de dire pourquoi, mais je pense que c'est un problème avec votre dispositif / système d'exploitation ARM. Avez-vous déjà essayé d'instrumenter le code de démarrage ou d'établir une liaison statique avec l'une des bibliothèques les plus utilisées pour voir si cela fait une grande différence? Placez également les bibliothèques partagées dans le même répertoire que l'application pour réduire le temps nécessaire à la recherche de la bibliothèque dans le système de stockage.

Une option qui me semble évidente est de lier statiquement tous les programmes en un seul fichier binaire. De cette façon, vous continuez à partager autant de code que possible (probablement plus qu'avant), mais vous éviterez également la surcharge de l'éditeur de liens dynamique ET vous épargnerez l'espace nécessaire pour avoir l'éditeur de liens dynamique sur le système.

Il est assez facile de combiner plusieurs exécutables dans le même, vous ne devez normalement examiner qu'argv et décider de la routine à appeler en fonction de cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top