Optimisation du judas - Peephole optimization
L'optimisation du judas est une technique d'optimisation réalisée sur un petit ensemble d'instructions générées par le compilateur; le petit ensemble est connu comme le judas ou la fenêtre.
L'optimisation du judas consiste à changer le petit ensemble d'instructions en un ensemble équivalent offrant de meilleures performances.
Par exemple:
- au lieu de pousser le registre A sur la pile, puis de replacer immédiatement la valeur dans le registre A, une optimisation du judas supprimerait les deux instructions;
- au lieu d'ajouter A à A, une optimisation du judas pourrait effectuer un décalage arithmétique vers la gauche;
- au lieu de multiplier un registre à virgule flottante par 8, une optimisation de judas pourrait mettre à l'échelle l'exposant du registre à virgule flottante par 3; et
- au lieu de multiplier un index par 4, d'ajouter le résultat à une adresse de base pour obtenir une valeur de pointeur, puis de déréférencer le pointeur, une optimisation de judas peut utiliser un mode d'adressage matériel qui produit le même résultat avec une instruction.
Le terme optimisation du judas a été introduit par William Marshall McKeeman en 1965.
Règles de remplacement
Techniques courantes appliquées à l'optimisation des judas:
- Null séquences - Supprimez les opérations inutiles.
- Combiner les opérations - Remplacez plusieurs opérations par un équivalent.
- Lois algébriques - Utilisez des lois algébriques pour simplifier ou réorganiser les instructions.
- Instructions pour cas spéciaux - Utilisez des instructions conçues pour les cas d'opérandes spéciaux.
- Opérations en mode adresse - Utilisez les modes d'adresse pour simplifier le code.
Il peut y avoir d'autres types d'optimisations de judas.
Exemples
Remplacement des instructions lentes par des instructions plus rapides
Le bytecode Java suivant
... aload 1 aload 1 mul ...
peut être remplacé par
... aload 1 dup mul ...
Ce type d'optimisation, comme la plupart des optimisations de judas, fait certaines hypothèses sur l'efficacité des instructions. Par exemple, dans ce cas, on suppose que l' dup
opération (qui duplique et pousse le haut de la pile ) est plus efficace que l' aload X
opération (qui charge une variable locale identifiée comme X
et la pousse sur la pile).
Suppression du code redondant
Un autre exemple consiste à éliminer les magasins de charge redondants.
a = b + c; d = a + e;
est directement implémenté comme
MOV b, R0 ; Copy b to the register
ADD c, R0 ; Add c to the register, the register is now b+c
MOV R0, a ; Copy the register to a
MOV a, R0 ; Copy a to the register
ADD e, R0 ; Add e to the register, the register is now a+e [(b+c)+e]
MOV R0, d ; Copy the register to d
mais peut être optimisé pour
MOV b, R0 ; Copy b to the register
ADD c, R0 ; Add c to the register, which is now b+c (a)
MOV R0, a ; Copy the register to a
ADD e, R0 ; Add e to the register, which is now b+c+e [(a)+e]
MOV R0, d ; Copy the register to d
Suppression des instructions de pile redondante
Si le compilateur enregistre les registres sur la pile avant d'appeler un sous-programme et les restaure lors du retour, les appels consécutifs aux sous-programmes peuvent avoir des instructions de pile redondantes.
Supposons que le compilateur génère les instructions Z80 suivantes pour chaque appel de procédure:
PUSH AF
PUSH BC
PUSH DE
PUSH HL
CALL _ADDR
POP HL
POP DE
POP BC
POP AF
S'il y avait deux appels de sous-programmes consécutifs, ils ressembleraient à ceci:
PUSH AF
PUSH BC
PUSH DE
PUSH HL
CALL _ADDR1
POP HL
POP DE
POP BC
POP AF
PUSH AF
PUSH BC
PUSH DE
PUSH HL
CALL _ADDR2
POP HL
POP DE
POP BC
POP AF
La séquence POP regs suivie de PUSH pour les mêmes registres est généralement redondante. Dans les cas où il est redondant, une optimisation judas supprimerait ces instructions. Dans l'exemple, cela entraînerait l'apparition d'une autre paire POP / PUSH redondante dans le judas, et celles-ci seraient supprimées à leur tour. En supposant que le sous-programme _ADDR2 ne dépend pas des valeurs de registre précédentes, la suppression de tout le code redondant dans l'exemple ci-dessus finirait par laisser le code suivant:
PUSH AF
PUSH BC
PUSH DE
PUSH HL
CALL _ADDR1
CALL _ADDR2
POP HL
POP DE
POP BC
POP AF
Mise en œuvre
Les compilateurs modernes implémentent souvent des optimisations de judas avec un algorithme de correspondance de modèles .
Voir également
- Optimiseurs de code objet , discussion sur l' efficacité algorithmique générale
- Capex Corporation - a produit l' optimiseur COBOL , un des premiers optimiseurs de code objet mainframe pour IBM Cobol
- Superoptimisation
- Digital Research XLT86 , un compilateur d'assemblage source à source optimisant
Les références
Liens externes
La définition du dictionnaire de l' optimisation du judas chez Wiktionary