50 votes

Utilisation du langage d'assemblage en C / C ++

Je me souviens avoir lu quelque part que pour vraiment optimiser la vitesse et jusqu'à une certaine section du code, les programmeurs d'écrire cet article dans le langage d'Assemblage. Mes questions sont les suivantes -

  1. Cette pratique est encore fait? et Comment fait-on cela?
  2. N'est pas écrit en Langage d'Assemblage un peu trop lourd & archaïque?
  3. Lorsque nous compiler du code C (avec ou sans l'option-O3 drapeau), le compilateur effectue une optimisation du code et liens toutes les bibliothèques et convertit le code binaire de l'objet fichier. Alors, quand on lance le programme, il est déjà dans sa forme la plus basique, c'est à dire binaire. Alors, comment induire de l'Assemblée de la Langue " de l'aide?

Je suis en train d'essayer de comprendre ce concept et de l'aide ou des liens est très apprécié.

Mise à JOUR: Reformuler le point 3, comme demandé par dbemerlin - Parce que vous pourriez être en mesure d'écrire plus efficace assemblée de code que le compilateur génère, mais sauf si vous êtes un assembleur expert, votre code sera probablement plus lent parce que, souvent, le compilateur optimise le code mieux que la plupart des humains peuvent.

32voto

Tony D Points 43962

Le seul moment où il est utile de revenir à l'assemblée de la langue, c'est quand

  • les instructions du PROCESSEUR n'ont pas d'équivalents fonctionnels en C++ (par exemple, les opérations atomiques, d'instruction unique-données multiples instructions explicites de mémoire cache de synchronisation, instructions uniques qui donnent des div et mod résultats)

    OU

  • pour des raisons inexplicables - l'optimiseur est de ne pas utiliser les meilleures instructions du PROCESSEUR

...ET...

  • l'utilisation de ces instructions du PROCESSEUR donner un peu important et utile dans l'augmentation des performances de goulot d'étranglement de code.

Tout simplement en utilisant assembly en ligne pour faire une opération qui peut facilement être exprimé en C++, comme l'ajout de deux valeurs ou à la recherche dans une chaîne est activement contre-productif, parce que:

  • le compilateur sait comment faire cela aussi bien
    • pour cela, vérifiez son assemblée de sortie (par exemple gcc-S) ou désassembler le code machine
  • vous êtes artificiellement la restriction de son choix quant à l'allocation de registres, instructions du PROCESSEUR, etc., ainsi, il peut prendre plus de temps pour préparer les registres du CPU avec les valeurs nécessaires à l'exécution de votre codé en dur instruction, alors plus de temps pour revenir à une allocation optimale pour de futures instructions
    • compilateur optimisateurs pouvez choisir entre l'équivalent de la performance des instructions précisant les différents registres, à minimiser la copie d'entre eux, et peut choisir des registres de telle manière qu'un seul core peut traiter plusieurs instructions au cours d'un cycle, alors que le forçage everythingt par le biais de registres serialise il
      • dans l'équité, la GCC a des moyens pour exprimer des besoins spécifiques des types de registres sans contraindre le CPU à un registre exact, en permettant à ces optimisations, mais c'est le seul assembly en ligne que j'ai jamais vu que l'adresse de ce
  • si un nouveau modèle de CPU sortira l'année prochaine avec une autre instruction que 1000% plus rapide pour la même opération logique, alors le compilateur fournisseur est plus probablement à mettre à jour leur compilateur d'utiliser cette instruction, et donc votre programme pour avantage une fois recompilé, que vous êtes
  • le compilateur choisira une approche optimale pour l'architecture cible de ses raconté: si vous coder en dur une solution, alors il aura besoin d'un plus petit dénominateur commun ou #ifdef-ed pour vos plateformes de
  • assemblée de la langue n'est pas aussi portable que C++, à la fois entre les Processeurs et à travers les compilateurs, et même si vous paraissez port d'une instruction, il est possible de faire une erreur re registres qui sont sûrs pour les fringues, argument en passant des conventions etc.
  • d'autres programmeurs peuvent ne pas savoir ou être à l'aise avec l'assemblée

D'un point de vue que je pense est bon de garder à l'esprit est que lorsque C a été introduit, il a dû gagner beaucoup de hardcore langage d'assemblage programmeurs qui s'agitait sur le code machine généré. Machines a moins de puissance CPU et de la RAM à l'époque, et vous pouvez parier que les gens se sont agités sur la plus petite des choses. Optimisateurs est devenu très sophistiqué et ont continué à s'améliorer, alors que l'assemblée langues de processeurs comme le x86 sont devenus de plus en plus compliqué, comme d'autres de leur exécution, les pipelines, les caches et d'autres facteurs impliqués dans leur performance. Vous ne pouvez pas ajouter des valeurs à partir d'une table de cycles par instruction plus. Les rédacteurs du compilateur prendre le temps d'examiner toutes ces subtiles facteurs (en particulier ceux qui travaillent pour les fabricants de processeurs, mais qui augmente la pression sur d'autres compilateurs trop). Il est maintenant impossible pour les programmeurs en assembleur en moyenne - plus de toutes les non-trivial de l'application de manière significative une meilleure efficacité de code que celle générée par une bonne optimisation du compilateur, et ils sont extrêmement probable à faire pire. Ainsi, l'utilisation de l'assemblage doit être limitée à la fois, il fait vraiment un mesurables et utiles différence, ça vaut le couplage et les coûts de maintenance.

15voto

sharptooth Points 93379

Tout d’abord, vous devez profiler votre programme. Ensuite, vous optimisez les chemins les plus utilisés en code C ou C ++. À moins que les avantages ne soient clairs, vous ne réécrivez pas dans l'assembleur . L'utilisation d'assembleur rend votre code plus difficile à maintenir et beaucoup moins portable - cela n'en vaut pas la peine, sauf dans de très rares situations.

11voto

Andreas Brinck Points 23806

(1) Oui, le moyen le plus simple d’essayer ceci est d’utiliser un assemblage en ligne, cela dépend du compilateur, mais ressemble généralement à ceci:

 __asm
{
    mov eax, ebx
}
 

(2) C'est très subjectif

(3) Parce que vous pourriez être en mesure d'écrire un code assembleur plus efficace que celui généré par le compilateur.

6voto

kriss Points 10450

Vous devriez lire le livre classique de l' Zen of Code Optimization et le suivi Zen of Graphics Programming par Michael Abrash.

Sommairement dans le premier livre, il explique comment utiliser l'assemblage de programmation poussés à la limite. Dans le cadre du suivi-il expliquer que les programmeurs devraient certains utilisent le langage de plus haut niveau comme le C et seulement essayer d'optimiser certaines taches à l'aide de l'assemblée, si nécessaire.

Une motivation de ce changement d'esprit était qu'il ne voyait que très optimisé les programmes de génération de processeur pourrait devenir (un peu) la lenteur dans la prochaine génération de la même famille de processeur par rapport à code compilé à partir d'un langage de haut niveau (maube compilateur à l'aide de nouvelles instructions, par exemple).

Une autre raison est que les compilateurs sont très bons et d'optimiser de manière agressive aujourd'hui, il y a généralement beaucoup plus de performance à acquérir en travaillant sur des algorithmes de conversion de code C à l'assemblée. Même pour les GPU (Cartes Graphiques processeurs) de la programmation, vous pouvez le faire à l'aide de C à l'aide de cuda ou OpenCL.

Il y a encore quelques (rares) cas où vous devez utiliser de l'assemblée, habituellement pour obtenir un réglage très fin sur le matériel. Mais même dans les OS code du noyau, il est généralement de très petites pièces et pas beaucoup de code.

4voto

Blindy Points 26706

Il y a très peu de raisons d'utiliser la langue assemblage de ces jours, même à faible niveau de constructions comme de l'ESS et de l'âge de MMX ont intégré intrinsèques à la fois cgc et MSVC (cpi trop je parie, mais je n'ai jamais utilisé).

Honnêtement, les optimiseurs de ces jours sont si incroyablement agressif que la plupart des gens ne pouvaient pas égale à la moitié de leur performance à l'écriture de code en assembleur. Vous pouvez changer la façon dont les données sont commandés en mémoire (localité) ou de dire au compilateur plus au sujet de votre code (par #pragma), mais en fait, l'écriture de code assembleur... de doute, vous obtiendrez quelque chose de cela.

@VJo, notez que l'utilisation de intrinsèques de haut niveau en code C vous laisser faire les mêmes optimisations, sans l'aide d'une seule instruction de montage.

Et pour ce que ça vaut, il y a eu des discussions au sujet de la prochaine compilateur C++ de Microsoft, et comment ils tomberont assembly en ligne à partir d'elle. Qui parle des volumes au sujet de la nécessité pour elle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X