10
votes

STL dans l'environnement embarqué

Je suis un programmeur C ++ et au fil des ans au fil des ans d'avoir entendu la notion que STL est pas bon pour une utilisation dans des environnements intégrés et donc généralement interdit dans l'utilisation de l'utilisation de des projets basés sur l'environnement intégré. Je crois que les bibliothèques STL comme Boost sont beaucoup plus puissantes et offrent un moyen de développement sujets beaucoup plus rapide et moins plus rapide et moins d'erreur (bien-être que la syntaxe est peu intimidante, mais une fois que je pense que c'est un véritable trésor) .so, je Trouvez les affirmations que STL est lourde et augmente l'empreinte finale du code Absurd parce que, puisque elle est template, on ne va que pour obtenir un code compilable qu'il a demandé et non à l'ensemble de la STL.

Ma question est de savoir quelles sont les raisons de cette population (au moins la plupart des peeps autour de moi pensent que oui) notion qui appelle STL est pas pour un environnement intégré?

Je vois une question de nature similaire, mais je m'attends à ce que je m'attends à l'aide pour souligner les avantages et les inconvénients en général à propos de STL et de respiornment intégré ici.

Edit: Alors ici, je vais ajouter les points car les réponses arrivent:
1. Problèmes de portabilité
2. Faire face à d'énormes allocations de dymanice par des conteneurs stl
3. STL est difficile de déboguer
4. Appels de fonction approfondis dans les résultats de STL dans la faible performance pour les compilateurs faibles avec l'inlinisation (puissance des foncteurs inutiles!)


1 commentaires

Je suis d'accord avec vous sur le point de la taille du code généré. J'ai constaté que le code généré de STL à très compact, beaucoup plus petit que le code construit à la main pour tous les exemples sauf triviaux.


11 Réponses :


1
votes

Beaucoup pensent que (pour de nombreuses raisons, telles que la portabilité) C ++ n'est pas un bon ajustement pour un environnement intégré. Il existe de nombreux types d'environnements intégrés et STL est certainement correct pour certains d'entre eux.

En général, «plus puissant» est toujours une phrase de peur lorsque vous devez choisir quelque chose pour un environnement contraint des ressources, comme vous le souhaitez souvent quelque chose de moins puissant et plus contrôlable. Surtout si «plus puissant» signifie que le développeur (ou celui qui maintient le code ultérieurement) aurait moins de compréhension de la mise en œuvre sous-jacente.


0 commentaires

2
votes

Je pense que le choix dépend de votre ou des plate-forme ciblée. Si vous avez un compilateur C ++ correct et ne vous dérangeez pas de la mémoire dynamique allouée si vous utilisez des conteneurs, je ne vois aucun problème.


0 commentaires

8
votes

Cela dépend de ce que vous entendez par intégré. Sur les systèmes Atmel8, il y a très peu de bélier. Si peu que vous ne pouvez pas vraiment avoir un malloc raisonnable. Vous voulez, dans ce cas, gérer la mémoire très explicitement, probablement avec des tableaux statiques du type dont vous avez besoin. Si vous avez cela, vous n'avez essentiellement pas besoin de la majeure partie de la STL.

sur les systèmes de bras, vous avez beaucoup de RAM. Utilisez STL!


2 commentaires

+1 pour souligner que "intégré" couvre une large gamme de systèmes de minuscules microcontrôleurs à quelques centaines de octets de RAM jusqu'aux systèmes haut de gamme avec beaucoup gb De RAM - En règle générale, la STL peut être appropriée pour les systèmes intégrés intermédiaires intermédiaires et probablement pas pour les systèmes bas de gamme.


Il ne faut pas beaucoup RAM pour avoir de bons résultats avec des collections dynamiques. 10 kbytes sont probablement utilisables.



9
votes

stl a de nombreux problèmes (comme documenté ici par Eastl ), sur un système intégré ou un système à petite échelle, le problème principal est généralement la manière dont elle gère (sa) mémoire. Le PSP Port d'Aquaria . < / p>

mon conseil, bien que ce soit premier test, avant de suivre les hypothèses , si le test montre votre utilisation de trop de cycles spatiaux / processeurs, alors peut-être une optimisation ou deux pourraient le pousser dans le royaume de ' utilisable '.

Enfin, Boost est basé sur un modèle, donc si vous envisagez de la taille du code de modèle généré, cela souffrira de la même manière que STL.

EDIT / MISE À JOUR:

Pour effacer ma dernière déclaration (qui faisait simplement référence à Boost vs stl). Dans C, vous pouvez (AB) Utilisez le même code pour effectuer le même travail sur différentes structures partageant la même en-tête (ou la même mise en page), mais avec des modèles, chaque type peut obtenir sa propre copie (je n'ai jamais testé si aucun compilateur est Assez intelligemment pour le faire si "optimiser la taille" est en complete), même si c'est exactement la même chose (sur une machine / niveau d'assemblage) comme une qui vient d'être générée. Boost a l'avantage d'être beaucoup plus propre à lire et d'avoir de beaucoup plus de choses entassés, mais cela peut conduire à de longues périodes de compilation en raison d'une quantité de copie d'en-têtes (énormes) de Somtimes). STL gains parce que vous pouvez transmettre votre projet et ne nécessite pas de téléchargement / accompagnement de boost.


6 commentaires

@Nécrolis merci pour le lien et la réponse! Je ne comprends pas cependant "souffrir de la même chose que STL", je le pense (stimuler aussi bien que STL) ne génère que le code qui est appelé, donc c'est une bonne chose juste, avez-vous voulu dire "comportement" au lieu de "souffrir"?


+1 pour le lien vers Eastl. Mais je me demande combien la STL a changé depuis lors


@drhirsch: la mise en œuvre peut avoir un changement, mais la gestion de la mémoire n'a pas pour les compilateurs que je connaisse; C'est-à-dire que la mémoire saisie pour les conteneurs STL n'est pas libérée et plus peut être saisie ce que vous voulez. Dans l'environnement contraint de la mémoire, cela peut être ennuyeux.


Il n'y a pas beaucoup d'algorithmes dans ce lien, il se peut que STL utilisés avec des matrices statiques soit utilisable où les conteneurs ne sont pas? tout le monde se concentre sur les structures de données, mais ce n'est que la moitié de l'image


L'idée "mémoire" est un peu défectueuse de toute façon. Pourquoi voudriez-vous jamais libérer la mémoire sur un système intégré? L'utilisateur peut donc exécuter un autre programme? Pas sur un système embarqué. Et ces systèmes embarqués suffisamment complexes pour exécuter deux applications ont tendance à exécuter de vrais OS'ES.


@Msalters: Cela dépend vraiment du système intégré et de ce que c'est tenter de faire, vous aurez même besoin d'un allocator personnalisé pour les sections de mémoire réservées, car Cause :: Nouveau pourrait commencer à allouer des choses qu'il ne devrait pas aller 't. @JK: C'est un bon point, j'ai supposé qu'ils n'ont pas trouvé de problèmes avec l'algo, à l'exception des rares choses mentionnées dans le document. @Als: Je dirais que je dirais que les deux travaux, en fonction de la stationnement, si vous avez 5 structures, toutes identiques, mais à l'aide de modèles, le compilateur pourrait (probablement) ne pas coaller le code, je vais le faire un peu plus clair dans mon réponse :)



3
votes

Je suis tombé sur cette présentation: Standard C ++ pour la programmation des systèmes embarqués < / p>

La majeure partie de la complexité avec des modèles est avec le compilateur que dans le système d'exécution et qui est en partie où le problème réside - comme nous ne savons pas avec certitude la mesure d'une optimisation que le compilateur est capable d'accomplir. En fait, C ++ Code basé sur STL est censé être plus compact et plus rapide que le code C ++ n'utilisant pas de modèles et même C code!


1 commentaires

+1 Pour les optimisations, il peut être utile de mentionner que la bibliothèque / binaire résultante pourrait être plus grande, encore une fois, une fois, il faut mesurer.



0
votes

Pour moi, seulement bonne raison, de ne pas utiliser une bibliothèque si elle ne correspond pas à des contraintes limitées ou que sa taille peut être un problème plus tard. Si ce n'est pas un problème pour vous, allez-y. En tout cas, vous ne pouvez pas aller mieux.


0 commentaires

0
votes

Je n'ai connu aucun inconvénient à utiliser le STL dans des systèmes embarqués et je prévois de l'utiliser dans mon projet actuel. Boost aussi.


0 commentaires

3
votes

Il existe une certaine logique derrière la notion que les modèles conduisent à un code plus vaste. L'idée de base est assez simple: chaque instanciation d'un modèle produit essentiellement un code séparé. Cela était particulièrement problématique avec les compilateurs précoces - car les modèles (généralement) doivent être mis dans des en-têtes, toutes les fonctions d'un modèle sont en ligne . Cela signifie que si vous avez (par exemple) vecteur instancié dans 10 fichiers différents, vous (théoriquement) disposez de 10 copies distinctes de chaque fonction membre que vous utilisez, une pour chaque fichier dans lequel vous l'utilisez. .

Tout compilateur raisonnablement récent (moins de 10 ans) aura une certaine logique dans la liaison pour fusionner ces réunis, donc instanciateur vecteur sur 10 fichiers n'entraînera que 10 fichiers. Une copie de chaque fonction membre que vous avez utilisée entrer dans l'exécutable final. Pour le meilleur ou le pire, cependant, une fois qu'il est devenu "connu" que les modèles produisent du code ballonné, beaucoup de gens n'ont pas regardé à nouveau pour voir si elle est restée vraie.

Un autre point (qui reste vrai) est que les modèles peuvent faciliter la création d'un code assez complexe. Si vous écrivez des choses à vous-mêmes en C, vous êtes généralement fortement motivé à utiliser l'algorithme, la collection, etc. le plus simple pouvant faire le travail - suffisamment motivé que vous êtes susceptible de vérifier dans des détails tels que le nombre maximum d'articles que vous pourriez rencontrer pour voir si vous pouvez vous échapper avec quelque chose de vraiment simple. Un modèle peut le rendre si facile d'utiliser une collection à usage général que vous ne vous souciez pas de vérifier des choses comme ça, alors (par exemple), vous vous retrouvez avec tout le code pour construire et maintenir un arbre équilibré, même si vous êtes seulement Stockage (disons) 10 articles au mieux, un tableau simple avec des recherches linéaires sauveriez la mémoire et courait généralement plus rapidement.


5 commentaires

Concernant le "BLOAT": même si tout type de type de type, l'utilisation de Void * signifie qu'une version unique des collections / fonctions existent alors que le modèle est au moins une instanciation par type qu'il est instancié avec . Je ne m'inquiète pas pour le codage du serveur, mais pour l'environnement contraint de la mémoire, cela pourrait être une peine.


En fait, de nombreux compilateurs (même MSVC ++ pour Win32, où BLOAT n'est pas une grande inquiétude) sont capables de plier plusieurs fonctions ensemble, tant qu'ils sont binaires identiques. std :: Liste et std :: Liste est susceptible de partager la plupart des membres (si Tailleof (int) == Taillef (flotteur) bien sûr).


@Msalters: Oui, comme je l'ai dit, assez presque tous les compilateurs C ++ au cours des 10 dernières années environ peuvent le faire. Si la mémoire sert, Mme l'a ajouté en VC ++ 5.0, il y a environ 15 ans (il aurait peut-être été précédemment - ma mémoire du timing n'est même plus proche de clarifier).


J'ai compris votre réponse pour faire référence à l'élimination des multiples instantanations de la même fonction de différentes tues. C'est plutôt nécessaire car une fonction doit avoir une seule adresse.


@Msalters: Oui - au moins si la mémoire sert, c'était là encore plus tôt (je crois que VC ++ 4.0, bien que le même avertissement sur ma mémoire signifie).



2
votes

Comme les gens ont dit, il existe une large gamme de systèmes "intégrés". Je vais donner mon point de vue, qui se concentre sur les systèmes de sécurité critiques et difficiles.

La plupart des directives pour les systèmes critiques de sécurité interdisent simplement l'utilisation d'allocations de mémoire dynamiques. Il est tout simplement beaucoup plus facile et plus sûr de concevoir le programme si vous n'avez jamais à vous soucier d'un malloc / nouvel appel échouant. Et pour les systèmes de course à longueur de longueur où la fragmentation de tas peut se produire, vous ne pouvez pas prouver facilement que l'allocation de la mémoire n'échoue pas, même sur une puce / système avec de grandes quantités de mémoire (en particulier lorsque l'appareil doit fonctionner pendant des années sans redémarrer).

Dans les scénarios où il existe des délais de chronométrage serrés, les incertitudes impliquées dans une allocation de mémoire dynamique et l'instanciation des objets complexes sont souvent trop grandes pour traiter. C'est pourquoi de nombreux programmeurs qui travaillent dans ces zones collent avec C. Vous pouvez regarder la source C et deviner combien de temps une opération prend une opération. Avec C ++, il est plus facile pour un code simple à la recherche de plus de temps que ce qu'il semble. Ceux qui utilisent C ++ dans de tels systèmes ont tendance à coller à un code de vanille simple simple. Et le code qui est généralement rapide, mais prend parfois beaucoup de temps à exécuter est pire que le code plus lent mais cohérent.

Ce que j'ai fait dans des projets plus importants est d'isoler les fonctions en temps réel et critiques du reste. Les trucs non critiques peuvent être écrits à l'aide d'outils standard tels que la STL. Ça va tant que le système d'exploitation n'entre pas dans la voie des parties critiques. Et si je ne peux pas garantir qu'il n'y a pas de telles interactions, n'utilisez pas du tout les outils.


0 commentaires

2
votes

J'étais sur un projet intégré utilisé C ++ et STL dans un système très contraint (mémoire dans une fraction d'un mégaoctet, armv4 à basse vitesse). Pour la plupart, STL était super, mais il y avait des parties que nous avons dû sauter (par exemple, STD :: Carte requise 2-4k de code par instanciation [qui est un grand nombre par rapport à notre taille de la ROM] et nous avons eu Notre propre remplacement personnalisé pour STD :: Bitset [C'était peut-être ~ 1k Rom]). Mais, std :: vecteur et std :: liste étaient très utiles, comme l'utilisait Boost :: intrusion_ptr pour le comptage de référence (Shared_ptr était trop gros, environ 40 octets Ram par objet!).

L'un des inconvénients à l'aide de STL Est-ce que vous n'avez pas de récupération d'erreur lorsque des exceptions sont désactivées (qu'ils étaient pour nous, comme des exceptions et de la RTTI n'étaient pas bon marché sur notre compilateur). Par exemple, si une allocation de mémoire a échoué quelque part dans le code de cette ligne (Objet STD :: Map): P>

my_map[5] = 66;


0 commentaires

1
votes

Cela dépend de la nature du système embarqué.

Un tel système peut avoir quelques kilo-octets de RAM (ou moins), ou peut avoir de nombreux mégaoctets ou même des gigaoctets. Les contraintes de mémoire peuvent donc être une question.

Si le système contient des contraintes en temps réel, certaines pièces ou utilisations de STL peuvent ne pas être adaptées à certaines parties de votre application. Les classes de conteneurs s'appuient fortement sur l'allocation de mémoire dynamique, la réaffectation et la copie d'objet, ce qui est le plus souvent très déterministe, donc utilisé dans le code critique, vous n'avez aucun moyen de garantir la réunion des délais.

Cela ne veut pas dire que STL ne peut pas être utilisé, même dans des applications en temps réel. Mais vous devez concevoir le code avec soin afin que vous sachiez que certaines opérations non déterministes ne se produiront pas pendant un processus critique de temps.


0 commentaires