Pourquoi programmez-vous en assemblage? [fermé]


86

J'ai une question pour tous les hackers hardcore de bas niveau. J'ai parcouru cette phrase dans un blog. Je ne pense pas vraiment que la source compte (c'est Haack si vous vous souciez vraiment) parce que cela semble être une déclaration commune.

Par exemple, de nombreux jeux 3-D modernes ont leur moteur de base haute performance écrit en C ++ et Assembly.

En ce qui concerne l'assembly, le code est-il écrit en assembly parce que vous ne voulez pas qu'un compilateur émette des instructions supplémentaires ou utilise un nombre excessif d'octets, ou utilisez-vous de meilleurs algorithmes que vous ne pouvez pas exprimer en C (ou ne pouvez pas exprimer sans le compilateur les mussing)?

Je comprends parfaitement qu'il est important de comprendre les choses de bas niveau. Je veux juste comprendre le programme pourquoi dans l'assemblage après l'avoir compris.


1
Des questions similaires sont déjà là, je pense ...
Mehrdad Afshari

8
Eeeeehh .. techniquement, c'est une question différente. Ces questions sont à la fois pourquoi apprendre l'assemblage, c'est pourquoi programmer dedans, qui .. je pense que c'est différent ....?
cgp

4
Pourquoi programmez-vous en assemblage? - Regardons quelques réponses IMPOSSIBLES à ces questions: 1) Pour rendre mon code maintenable, 2) flexible, 3) pour assurer la portabilité, 4) la testabilité, 5) la lisibilité, ...;)
ivan_ivanovich_ivanoff

9
sécurité de l'emploi ........
San Jacinto

3
parce que c'est amusant .. :)
RainingComputers

Réponses:


169

Je pense que vous avez mal interprété cette déclaration:

Par exemple, de nombreux jeux 3-D modernes ont leur moteur de base haute performance écrit en C ++ et Assembly.

Les jeux (et la plupart des programmes de nos jours) ne sont pas «écrits en assemblage» de la même manière qu'ils sont «écrits en C ++». Ce blog ne dit pas qu'une fraction importante du jeu est conçue en assemblage, ou qu'une équipe de programmeurs s'assoit et se développe en assemblage comme langue principale.

Ce que cela signifie vraiment , c'est que les développeurs écrivent d'abord le jeu et le font fonctionner en C ++. Ensuite, ils le profilent, déterminent quels sont les goulots d'étranglement et si cela en vaut la peine, ils en optimisent le diable lors de l'assemblage. Ou, s'ils sont déjà expérimentés, ils savent quelles parties vont être des goulots d'étranglement, et ils ont des pièces optimisées provenant d'autres jeux qu'ils ont construits.

Le point de la programmation dans l'assemblage est le même qu'il l'a toujours été: la vitesse . Il serait ridicule d'écrire beaucoup de code dans l'assembleur, mais il y a certaines optimisations dont le compilateur n'est pas conscient, et pour une fenêtre de code assez petite, un humain fera mieux.

Par exemple, pour la virgule flottante, les compilateurs ont tendance à être assez conservateurs et peuvent ne pas être conscients de certaines des fonctionnalités les plus avancées de votre architecture. Si vous êtes prêt à accepter une erreur, vous pouvez généralement faire mieux que le compilateur, et cela vaut la peine d'écrire ce petit morceau de code en assembly si vous trouvez que beaucoup de temps y est consacré.

Voici quelques exemples plus pertinents:

Exemples de jeux

  • Article d'Intel sur l'optimisation d'un moteur de jeu en utilisant les intrinsèques SSE. Le code final utilise des éléments intrinsèques (pas un assembleur en ligne), de sorte que la quantité d'assemblage pur est très petite. Mais ils regardent la sortie de l'assembleur par le compilateur pour déterminer exactement ce qu'il faut optimiser.

  • Racine carrée inverse rapide de Quake . Encore une fois, la routine ne contient pas d'assembleur, mais vous devez savoir quelque chose sur l'architecture pour faire ce type d'optimisation. Les auteurs savent quelles opérations sont rapides (multiplier, déplacer) et lesquelles sont lentes (diviser, sqrt). Ils proposent donc une implémentation très délicate de la racine carrée qui évite complètement les opérations lentes.

Calcul haute performance

  • En dehors du domaine des jeux, les spécialistes de l'informatique scientifique optimisent fréquemment la merde des choses pour les faire fonctionner rapidement sur le dernier matériel. Pensez à cela comme à des jeux où vous ne pouvez pas tricher sur la physique.

    Un bon exemple récent de ceci est la Chromodynamique Quantique Lattice (Lattice QCD) . Cet article décrit comment le problème se résume assez bien jusqu'à un très petit noyau de calcul, qui a été optimisé fortement pour PowerPC 440 est sur un IBM Blue Gene / L . Chaque 440 a deux FPU, et ils prennent en charge certaines opérations ternaires spéciales qui sont difficiles à exploiter pour les compilateurs. Sans ces optimisations, Lattice QCD aurait fonctionné beaucoup plus lentement, ce qui est coûteux lorsque votre problème nécessite des millions d'heures de processeur sur des machines coûteuses.

    Si vous vous demandez pourquoi c'est important, consultez l' article dans Science qui est sorti de ce travail. En utilisant Lattice QCD, ces gars ont calculé la masse d'un proton à partir des premiers principes et ont montré l'année dernière que 90% de la masse provient d'une énergie de liaison de force forte et le reste des quarks. C'est E = mc 2 en action. Voici un résumé .

Pour tout ce qui précède, les applications ne sont pas conçues ou écrites à 100% en assemblage - même pas proches. Mais lorsque les gens ont vraiment besoin de vitesse, ils se concentrent sur l'écriture des parties clés de leur code pour voler sur un matériel spécifique.


12
réponse incroyable. Je souhaite que nous puissions mettre cela dans un wiki!
bdd

6
@Paperino ... vous pouvez. Les questions et réponses sur StackOverflow sont une attribution Creative Commons sous licence.
Aaron Maenpaa

Pour plus d'informations sur la compréhension d'ASM pour vous aider à écrire un meilleur C / C ++, consultez Pourquoi ce code C ++ est-il plus rapide que mon assembly écrit à la main pour tester la conjecture de Collatz? . Ma réponse souligne que la lecture de la sortie asm du compilateur et l'ajustement de la source peuvent aider lorsque le compilateur ne remarque pas une optimisation utile. Donc, vous écrivez mentalement (ou réellement) en asm, puis tenez le compilateur à la main pour faire ce que vous voulez, mais maintenant vous avez un C. portable à l'épreuve du temps
Peter Cordes

42

Je n'ai pas codé en langage d'assemblage depuis de nombreuses années, mais je peux donner plusieurs raisons que j'ai souvent vues:

  • Tous les compilateurs ne peuvent pas utiliser certaines optimisations du processeur et certains jeux d'instructions (par exemple, les nouveaux jeux d'instructions qu'Intel ajoute de temps en temps). Attendre que les rédacteurs du compilateur rattrapent leur retard signifie perdre un avantage concurrentiel.

  • Il est plus facile d'associer le code réel à l'architecture et à l'optimisation connues du processeur Par exemple, des choses que vous savez sur le mécanisme de récupération, la mise en cache, etc. Ceci est censé être transparent pour le développeur, mais le fait est que ce n'est pas le cas, c'est pourquoi les rédacteurs de compilateurs peuvent optimiser.

  • Certains accès au niveau matériel ne sont possibles / pratiques que via le langage d'assemblage (par exemple, lors de l'écriture du pilote de périphérique).

  • Le raisonnement formel est parfois en fait plus facile pour le langage assembleur que pour le langage de haut niveau puisque vous savez déjà quelle est la mise en page finale ou presque finale du code.

  • La programmation de certaines cartes graphiques 3D (vers la fin des années 1990) en l'absence d'API était souvent plus pratique et efficace en langage assembleur, et parfois impossible dans d'autres langages. Mais encore une fois, cela impliquait des jeux de niveau vraiment expert basés sur l'architecture de l'accélérateur, comme le déplacement manuel des données d'entrée et de sortie dans un certain ordre.

Je doute que beaucoup de gens utilisent le langage assembleur alors qu'un langage de niveau supérieur ferait l'affaire, surtout quand ce langage est C. L'optimisation manuelle de grandes quantités de code à usage général n'est pas pratique.


19

Il y a un aspect de la programmation assembleur que d'autres n'ont pas mentionné - le sentiment de satisfaction que vous ressentez en sachant que chaque octet d'une application est le résultat de vos propres efforts, pas de ceux du compilateur. Je ne voudrais pas une seconde revenir à l'écriture d'applications entières en assembleur comme je le faisais au début des années 80, mais ce sentiment me manque parfois ...


3
Hé, c'est le résultat du travail d'assembleur! Vous écrivez généralement beaucoup de macros dans asm.
Mehrdad Afshari

5
Pas seulement une satisfaction, mais une appréciation de la précision. Un processus concis avec tout ce qui est déclaré est une joie à voir.
deau

18

Habituellement, l'assemblage d'un profane est plus lent que C (en raison de l'optimisation de C) mais de nombreux jeux (je me souviens distinctement de Doom ) devaient avoir des sections spécifiques du jeu dans Assembly afin qu'il fonctionne correctement sur des machines normales.

Voici l'exemple auquel je fais référence.


2
+1 Très vrai. Les humains sont très mauvais pour écrire du code long asm.
Compte mort le

Gardez à l'esprit que ces outils n'étaient pas toujours disponibles lors de l'écriture de l'assembleur.
Marco van de Voort

16

J'ai commencé la programmation professionnelle en langage assembleur dans mon tout premier emploi (années 80). Pour les systèmes embarqués, les demandes de mémoire - RAM et EPROM - étaient faibles. Vous pouvez écrire un code serré qui est facile sur les ressources.

À la fin des années 80, j'étais passé à C. Le code était plus facile à écrire, déboguer et maintenir. De très petits extraits de code ont été écrits en assembleur - pour moi, c'était lorsque j'écrivais le changement de contexte dans un RTOS roll-your-own. (Quelque chose que vous ne devriez plus faire à moins qu'il ne s'agisse d'un "projet scientifique".)

Vous verrez des extraits d'assembleur dans certains codes du noyau Linux. Plus récemment, je l'ai parcouru dans spinlocks et autre code de synchronisation. Ces morceaux de code doivent avoir accès aux opérations de test et de définition atomiques, à la manipulation des caches, etc.

Je pense que vous auriez du mal à sur-optimiser les compilateurs C modernes pour la plupart de la programmation générale.

Je suis d'accord avec @altCognito pour dire que votre temps est probablement mieux dépensé à réfléchir davantage au problème et à mieux faire les choses. Pour une raison quelconque, les programmeurs se concentrent souvent sur la micro-efficacité et négligent les macro-efficiences. Le langage d'assemblage pour améliorer les performances est une micro-efficacité. Prendre du recul pour une vue plus large du système peut exposer les problèmes de macro dans un système. La résolution des problèmes macro-économiques peut souvent générer de meilleurs gains de performances. Une fois que les problèmes macro sont résolus, réduisez au niveau micro.

Je suppose que les micro-problèmes sont sous le contrôle d'un seul programmeur et dans un domaine plus petit. Modifier le comportement au niveau macro nécessite une communication avec plus de personnes - une chose que certains programmeurs évitent. Tout ce cowboy contre l'équipe.


10

"Oui". Mais comprenez que pour la plupart, les avantages de l'écriture de code en assembleur ne valent pas la peine. Le retour reçu pour l'écrire en assemblage a tendance à être plus petit que le simple fait de se concentrer sur une réflexion plus approfondie sur le problème et de passer son temps à réfléchir à une meilleure façon de faire les choses.

John Carmack et Michael Abrash, qui étaient en grande partie responsables de l'écriture de Quake et de tout le code haute performance qui a été utilisé dans les moteurs de jeu ID, approfondissent ce sujet dans ce livre .

Je suis également d'accord avec Ólafur Waage pour dire qu'aujourd'hui, les compilateurs sont assez intelligents et utilisent souvent de nombreuses techniques qui tirent parti des améliorations architecturales cachées.


9

De nos jours, pour les codes séquentiels au moins, un compilateur décent bat presque toujours même un programmeur en langage d'assemblage hautement expérimenté. Mais pour les codes vectoriels, c'est une autre histoire. Les compilateurs largement déployés ne font pas un si bon travail en exploitant les capacités de parallélisme vectoriel de l'unité x86 SSE, par exemple. Je suis un rédacteur de compilateurs, et l' exploitation de SSE est en tête de ma liste de raisons de partir seul au lieu de faire confiance au compilateur.


Dans ce cas, j'utiliserais un compilateur intrinsèque.
Mehrdad Afshari

Pas toujours pareil. C'est comme un compilateur sans optimiseur de registre
Marco van de Voort

Cela dépend du type d'assaisonnement de votre programmeur asm. Si vous avez lu et grokked agner.org/optimize pour en savoir plus sur la microarchitecture que vous réglez , battre le compilateur pour de courtes séquences est souvent facile . Au moins la moitié du temps, je vois des optimisations mineures manquées lorsque je regarde la sortie du compilateur pour les petites fonctions. Là où les compilateurs sont excellents, c'est l'optimisation sur de grandes bases de code avec une propagation en ligne et constante.
Peter Cordes

8

Le code SSE fonctionne mieux dans l'assembly que les intrinsèques du compilateur, du moins dans MSVC. (c'est-à-dire ne crée pas de copies supplémentaires des données)


Bon point, vous avez besoin d'un compilateur qui fait un travail décent avec des intrinsèques. Les compilateurs Intel et Gnu sont assez bons, je ne sais pas si les derniers de PGI et PathScale sont encore compétitifs, ils ne l'étaient pas avant.
Jed

6

J'ai trois ou quatre routines d'assembleur (dans environ 20 Mo de source) dans mes sources au travail. Tous sont SSE (2) , et sont liés à des opérations sur des images (assez grandes - pensez à 2400x2048 et plus).

Pour les loisirs, je travaille sur un compilateur, et là vous avez plus d'assembleur. Les bibliothèques d'exécution en sont assez souvent pleines, la plupart d'entre elles ont à voir avec des choses qui défient le régime procédural normal (comme les aides pour les exceptions, etc.)

Je n'ai pas d'assembleur pour mon microcontrôleur. La plupart des microcontrôleurs modernes ont tellement de matériel périphérique (compteurs contrôlés par interruption, même codeurs en quadrature entiers et blocs de construction série) que l'utilisation de l'assembleur pour optimiser les boucles n'est souvent plus nécessaire. Avec les prix flash actuels, il en va de même pour la mémoire de code. De plus, il existe souvent des gammes d'appareils compatibles avec les broches, donc la mise à l'échelle si vous manquez systématiquement de puissance CPU ou d'espace flash n'est souvent pas un problème

Sauf si vous expédiez vraiment 100000 appareils et l'assembleur de programmation permet de réaliser de véritables économies importantes en installant simplement une puce flash d'une catégorie plus petite. Mais je ne suis pas dans cette catégorie.

Beaucoup de gens pensent que l'embarqué est une excuse pour l'assembleur, mais leurs contrôleurs ont plus de puissance CPU que les machines sur lesquelles Unix a été développé. (Microchip livré avec 40 et 60 microcontrôleurs MIPS pour moins de 10 USD ).

Cependant, beaucoup de gens sont coincés avec l'héritage, car changer l'architecture de la micropuce n'est pas facile. Le code HLL est également très dépendant de l'architecture (car il utilise la périphérie matérielle, des registres pour contrôler les E / S, etc.). Il y a donc parfois de bonnes raisons de continuer à maintenir un projet en assembleur (j'ai eu la chance de pouvoir configurer les affaires sur une nouvelle architecture à partir de zéro). Mais souvent, les gens se disent qu'ils ont vraiment besoin de l'assembleur.

J'aime toujours la réponse d'un professeur lorsque nous avons demandé si nous pouvions utiliser GOTO (mais vous pouvez également lire cela en tant qu'ASSEMBLER): "si vous pensez que cela vaut la peine d'écrire un essai de 3 pages sur les raisons pour lesquelles vous avez besoin de cette fonctionnalité, vous pouvez l'utiliser . Veuillez soumettre l'essai avec vos résultats. "

J'ai utilisé cela comme principe directeur pour les fonctionnalités de bas niveau. Ne soyez pas trop à l'étroit pour l'utiliser, mais assurez-vous de le motiver correctement. Élevez même une barrière artificielle ou deux (comme l'essai) pour éviter un raisonnement alambiqué comme justification.


1
J'aime le test-essai; Je devrai peut-être l'utiliser plus souvent;)
ex nihilo

5

Certaines instructions / indicateurs / contrôles n'existent tout simplement pas au niveau C.

Par exemple, la vérification du débordement sur x86 est le simple indicateur de débordement. Cette option n'est pas disponible en C.


Vous pouvez calculer les indicateurs de débordement en C avec des opérations sur les bits.
swegi

@swegi: Je parie que c'est nettement plus lent.
Brian

à quelle fréquence est-ce utile? et quand c'est le cas, cela ne peut pas être la seule raison de tomber dans l'assembleur.

5

Les défauts ont tendance à s'exécuter par ligne (instruction, point de code, etc.); s'il est vrai que pour la plupart des problèmes, l'assembly utiliserait beaucoup plus de lignes que les langages de niveau supérieur, il y a parfois des cas où c'est la meilleure correspondance (la plus concise, le moins de lignes) avec le problème en question. La plupart de ces cas impliquent les suspects habituels, tels que les pilotes et le bit-bang dans les systèmes embarqués.


3

Une autre raison pourrait être lorsque le compilateur disponible n'est tout simplement pas assez bon pour une architecture et que la quantité de code nécessaire dans le programme n'est pas si longue ou complexe que le programmeur s'y perd. Essayez de programmer un microcontrôleur pour un système embarqué, généralement l'assemblage sera beaucoup plus facile.


3

A côté d'autres choses mentionnées, toutes les langues supérieures ont certaines limitations. C'est pourquoi certaines personnes choisissent de programmer en ASM, pour avoir un contrôle total sur leur code.

D'autres bénéficient de très petits exécutables, de l'ordre de 20 à 60 Ko, par exemple check HiEditor , qui est implémenté par l'auteur du contrôle HiEdit, un superbe contrôle d'édition puissant pour Windows avec coloration syntaxique et tabulations en seulement ~ 50 Ko). Dans ma collection, j'ai plus de 20 contrôles d'or de ce type d'Excell, comme des ssheets aux rendus html.


3

Je pense que beaucoup de développeurs de jeux seraient surpris par cette information.

La plupart des jeux que je connais utilisent le moins d'assemblage possible. Dans certains cas, pas du tout, et au pire, une ou deux boucles ou fonctions.

Cette citation est trop généralisée, et loin d'être aussi vraie qu'elle l'était il y a dix ans.

Mais bon, de simples faits ne devraient pas entraver la croisade d'un véritable hacker en faveur de l'assemblée. ;)


3

Si vous programmez un microcontrôleur 8 bits bas de gamme avec 128 octets de RAM et 4K de mémoire programme, vous n'avez pas beaucoup de choix sur l'utilisation de l'assemblage. Parfois, lorsque vous utilisez un microcontrôleur plus puissant, vous devez effectuer une certaine action à un moment précis. Le langage d'assemblage est alors utile car vous pouvez compter les instructions et ainsi mesurer les cycles d'horloge utilisés par votre code.


2

Si vous étiez là pour tous les efforts de remédiation de l'an 2000, vous auriez pu gagner beaucoup d'argent si vous connaissiez Assembly. Il y a encore beaucoup de code hérité qui y a été écrit, et ce code nécessite parfois une maintenance.


2

Mis à part de très petits projets sur de très petits processeurs, je ne voudrais jamais programmer un projet entier en assemblage. Cependant, il est courant de constater qu'un goulot d'étranglement de performance peut être soulagé avec le codage manuel stratégique de certaines boucles internes.

Dans certains cas, tout ce qui est vraiment nécessaire est de remplacer une construction de langage par une instruction que l'optimiseur ne peut pas attendre de comprendre comment utiliser. Un exemple typique est dans les applications DSP où les opérations vectorielles et les opérations de multiplication-accumulation sont difficiles à découvrir pour un optimiseur, mais un code facile à manipuler.

Par exemple, certains modèles du SH4 contiennent une matrice 4x4 et 4 instructions vectorielles. J'ai vu une énorme amélioration des performances d'un algorithme de correction des couleurs en remplaçant les opérations C équivalentes sur une matrice 3x3 par les instructions appropriées, au prix minime de l'agrandissement de la matrice de correction en 4x4 pour correspondre à l'hypothèse matérielle. Cela a été réalisé en écrivant pas plus d'une douzaine de lignes d'assemblage et en effectuant des ajustements correspondants aux types de données et au stockage associés dans une poignée d'endroits dans le code C environnant.


2

Cela ne semble pas être mentionné, alors j'ai pensé l'ajouter: dans le développement de jeux modernes, je pense qu'au moins une partie de l'assemblage en cours d'écriture n'est pas du tout pour le processeur. C'est pour le GPU, sous la forme de programmes de shader .

Cela peut être nécessaire pour toutes sortes de raisons, parfois simplement parce que le langage d'ombrage de niveau supérieur utilisé ne permet pas à l'opération exacte d'être exprimée dans le nombre exact d'instructions voulues, pour s'adapter à une contrainte de taille, à une vitesse ou à toute combinaison. . Comme d'habitude avec la programmation en langage assembleur, je suppose.


2

Presque tous les moteurs de jeux ou bibliothèques de taille moyenne à grande que j'ai vus à ce jour ont des versions d'assemblage optimisées à la main disponibles pour les opérations matricielles comme la concaténation de matrice 4x4. Il semble que les compilateurs passent inévitablement à côté de certaines des optimisations intelligentes (réutilisation des registres, déroulement des boucles d'une manière extrêmement efficace, profitant des instructions spécifiques à la machine, etc.) lorsqu'ils travaillent avec de grandes matrices. Ces fonctions de manipulation de matrice sont presque toujours des "hotspots" sur le profil.

J'ai également vu un assemblage codé à la main beaucoup utilisé pour l'envoi personnalisé - des choses comme FastDelegate, mais spécifiques au compilateur et à la machine.

Enfin, si vous avez des routines de service d'interruption, asm peut faire toute la différence dans le monde - il y a certaines opérations que vous ne voulez tout simplement pas faire sous interruption, et vous voulez que vos gestionnaires d'interruptions «entrent et sortent rapidement». .. vous savez presque exactement ce qui va se passer dans votre ISR si c'est dans asm, et cela vous encourage à garder les choses sanglantes courtes (ce qui est une bonne pratique de toute façon).


2

Les jeux sont assez gourmands en performances et bien qu'entre-temps les optimiseurs soient plutôt bons, un "maître programmeur" est toujours capable de gagner en performances en codant à la main les bonnes pièces dans l'assemblage.

Ne commencez jamais à optimiser votre programme sans le profiler au préalable. Après le profilage, vous devriez être en mesure d'identifier les goulots d'étranglement et si trouver de meilleurs algorithmes et autres ne le coupe plus, vous pouvez essayer de coder à la main certaines choses dans l'assemblage.


2

Je n'ai personnellement parlé à un développeur de son utilisation de l'assemblage. Il travaillait sur le firmware qui traitait des commandes d'un lecteur mp3 portable. Faire le travail en montage avait 2 objectifs:

  1. Vitesse: les délais devaient être minimes.
  2. Coût: en étant minime avec le code, le matériel nécessaire pour l'exécuter pourrait être légèrement moins puissant. Lors de la production de masse de millions d'unités, cela peut s'additionner.

2

Le seul codage assembleur que je continue de faire concerne le matériel embarqué avec des ressources limitées. Comme le mentionne leander, l'assemblage est toujours bien adapté aux ISR où le code doit être rapide et bien compris.

Une raison secondaire pour moi est de garder ma connaissance de l'assemblage fonctionnelle. Être capable d'examiner et de comprendre les étapes que le CPU prend pour faire mes enchères me fait du bien.


2

La dernière fois que j'ai écrit en assembleur, c'était quand je ne pouvais pas convaincre le compilateur de générer du code indépendant de la position et sans libc.

La prochaine fois, ce sera probablement pour la même raison.

Bien sûr, j'avais d'autres raisons .


2

Beaucoup de gens adorent dénigrer le langage assembleur parce qu'ils n'ont jamais appris à coder avec lui et ne l'ont rencontré que vaguement et cela les a laissés stupéfaits ou quelque peu intimidés. Les vrais programmeurs talentueux comprendront qu'il est insensé de dénigrer C ou Assembly parce qu'ils sont complémentaires. en fait, l'avantage de l'un est l'inconvénient de l'autre. Les règles syntaxiques organisées de C améliorent la clarté mais en même temps renoncent à tout le pouvoir de l'assemblage d'être libre de toute règle structurelle! Les instructions de code C sont faites pour créer un code non bloquant qui pourrait être soutenu force la clarté de l'intention de programmation, mais c'est une perte de puissance. En C, le compilateur n'autorisera pas de saut dans un if / elseif / else / end. Ou vous n'êtes pas autorisé à écrire deux boucles for / end sur diférentes variables qui se chevauchent, vous ne pouvez pas écrire de code auto-modifiable (ou pas de manière transparente et simple), etc. les programmeurs conventionnels sont effrayés par ce qui précède, et n'auraient aucune idée de comment utiliser même la puissance de ces approches car elles ont été élevées pour suivre les règles conventionnelles . Voici la vérité: aujourd'hui, nous avons une machine avec la puissance de calcul nécessaire pour faire beaucoup plus que l'application pour laquelle nous les utilisons, mais le cerveau humain est trop incapable de les coder dans un environnement de codage sans règle (= assemblage) et a besoin de règles restrictives qui réduit le spectre et simplifie le codage. J'ai moi-même écrit du code qui ne peut pas être écrit en code C sans devenir extrêmement inefficace à cause des limitations mentionnées ci-dessus. Et je n'ai pas encore parlé de la vitesse qui, selon la plupart des gens, est la principale raison d'écrire en montage, eh bien, si cela vous dérange est limité à penser en C, vous êtes l'esclave de votre compilateur pour toujours. J'ai toujours pensé que les maîtres des joueurs d'échecs seraient des programmeurs d'assemblage idéaux alors que les programmeurs C ne joueraient qu'à "Dames".


1
le code auto-modifiable n'est pas utile pour les performances sur la plupart des processeurs modernes, en dehors des scénarios JIT-once / run-many. Mais remplir des constantes comme des immédiats est une possibilité amusante. gotoCependant, C autorise les sauts non structurés dans une fonction. Inclusion dans un bloc à l'intérieur d'une if()boucle ou dans la même fonction. par exemple godbolt.org/z/IINHTg . Voir aussi le dispositif de Duff, utilisant switch / case dans une do{}while()boucle pour exprimer un saut dans une boucle déroulée. Mais à un moment donné, il peut devenir plus clair d'écrire dans asm si vous descendez à ce niveau de désordre.
Peter Cordes

1
(Bien sûr, le périphérique de Duff n'est utile que sur les machines avec un adressage post-incrément, sinon ces points d'entrée à l'intérieur de la boucle déroulée ne font que vaincre la plupart des objectifs de l'optimisation.)
Peter Cordes

1

Plus de vitesse, mais de contrôle . La vitesse viendra parfois du contrôle, mais c'est la seule raison de coder en assemblage. Toutes les autres raisons se résument au contrôle (c'est-à-dire l'optimisation SSE et autre main, les pilotes de périphérique et le code dépendant du périphérique, etc.).


1

Si je suis capable de surpasser GCC et Visual C ++ 2008 (également connu sous le nom de Visual C ++ 9.0), alors les gens seront intéressés à m'interroger sur la façon dont cela est possible.

C'est pourquoi, pour le moment, je lis simplement les choses en assemblage et j'écris simplement __asm ​​int 3 lorsque cela est nécessaire.

J'espère que cette aide ...


1

Je n'ai pas écrit en assemblage depuis quelques années, mais les deux raisons pour lesquelles j'en avais l'habitude étaient:

  • Le défi de la chose! J'ai traversé une période de plusieurs mois il y a des années où j'écrivais tout en assemblage x86 (à l'époque de DOS et de Windows 3.1). Cela m'a essentiellement appris un morceau d'opérations de bas niveau, d' E / S matérielles , etc.
  • Pour certaines choses, il a gardé une petite taille (encore une fois DOS et Windows 3.1 lors de l'écriture de TSR )

Je continue de regarder à nouveau l'assemblage de codage, et ce n'est rien de plus que le défi et la joie de la chose. Je n'ai aucune autre raison de le faire :-)


1

Une fois, j'ai repris un projet DSP que le programmeur précédent avait écrit principalement en code d'assemblage, à l'exception de la logique de détection de tonalité qui avait été écrite en C, en utilisant la virgule flottante (sur un DSP à virgule fixe!). La logique de détection de tonalité a fonctionné à environ 1/20 du temps réel.

J'ai fini par réécrire presque tout à partir de zéro. Presque tout était en C, à l'exception de quelques petits gestionnaires d'interruptions et de quelques dizaines de lignes de code liées à la gestion des interruptions et à la détection de fréquence de bas niveau, qui s'exécute plus de 100 fois plus vite que l'ancien code.

Une chose importante à garder à l'esprit, je pense, est que dans de nombreux cas, il y aura beaucoup plus de possibilités d'amélioration de la vitesse avec de petites routines que les grandes, surtout si l'assembleur écrit à la main peut tout ranger dans les registres mais un compilateur ne bien gérer. Si une boucle est suffisamment grande pour ne pas pouvoir tout garder dans les registres de toute façon, il y a beaucoup moins de possibilités d'amélioration.


0

La VM Dalvik qui interprète le bytecode pour les applications Java sur les téléphones Android utilise l'assembleur pour le répartiteur. Ce film (environ 31 minutes, mais il vaut la peine de regarder le film entier!) Explique comment

"il y a encore des cas où un humain peut faire mieux qu'un compilateur".


0

Je ne le fais pas, mais je me suis fait un devoir au moins d'essayer, et d'essayer dur à un moment donné dans l'avenir (bientôt j'espère). Cela ne peut pas être une mauvaise chose d'apprendre à en savoir plus sur les choses de bas niveau et comment les choses fonctionnent dans les coulisses lorsque je programme dans un langage de haut niveau. Malheureusement, le temps est difficile à trouver avec un emploi à temps plein en tant que développeur / consultant et parent. Mais je donnerai en temps voulu, c'est sûr.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.