Sous Linux, /proc/cpuinfo
permet de vérifier tous les indicateurs CPU de la machine de manière simple.
Habituellement, si un programme nécessite un sur-ensemble du jeu d'instructions d'une machine, le moyen le plus simple de le déterminer est de l'exécuter et de voir s'il génère un SIGILLsignal.
Mais dans mon cas, tous mes processeurs prennent en charge au moins SSE4.1 et AVX.
Alors, existe-t-il un moyen simple de vérifier si un binaire contient des instructions spéciales?
objdump --disassemble
effectue un démontage. Vous pouvez utiliserobjdump
pour générer une liste de mnémoniques. Il fait partie de Binutils, donc il est disponible sur les systèmes GNU Linux. De plus, les instructions supplémentaires peuvent être présentes mais peuvent ne pas être exécutées. Le programme pourrait avoir des gardes d'exécution.-mavx
pour vous assurer que le compilateur ne sélectionne que depuis AVX ISA, mais il existe des moyens de le contourner. Par exemple, l'assembleur en ligne peut généralement contourner les vérifications ISA du compilateur.Réponses:
J'ai sorti un programme à Rust qui essaie de le faire. Je pense que cela fonctionne, bien qu'il soit sans papiers et terriblement fragile:
https://github.com/pkgw/elfx86exts
Exemple d'utilisation:
la source
Je suis tombé sur le même problème lorsque j'essayais de comprendre les processus d'optimisation GCC et de savoir quelles instructions avaient ou non été utilisées pendant ce processus. Comme je ne suis pas amical avec le nombre énorme de codes d'opération, je cherchais un moyen de visualiser des instructions spécifiques (disons SSE3) dans le code désassemblé, ou au moins d'imprimer des statistiques minimales comme si et combien de ces instructions sont là dans le binaire.
Je n'ai trouvé aucune solution existante, mais la réponse de Jonathan Ben-Avraham s'est avérée très utile, car elle indique une excellente source (et même partiellement structurée) de codes d'opération. Sur la base de ces données, j'ai écrit un script Bash qui peut visualiser des jeux d'instructions spécifiques ou imprimer des statistiques à leur sujet
grep
lorsqu'ils sont alimentés par une sortie deobjdump
.La liste des codes d'opération a été convertie en un script Bash autonome qui est ensuite inclus (dans un but de meilleure lisibilité) dans le fichier principal que j'ai nommé simplement
opcode
. Étant donné que les opcodes dansgas.vim
( lesvim
définitions de la syntaxe de Shirk , d'après la réponse de Jonathan) étaient systématiquement regroupés (apparemment) selon différentes architectures CPU, j'ai essayé de préserver cette division et de faire un mappage de jeu d'instructions architecture-> ; Je ne sais pas maintenant si c'était une bonne idée. Le mappage n'est pas précis et j'ai même dû faire quelques changements dans l'originalgas.vim
regroupement. Étant donné que les jeux d'instructions liés à l'architecture n'étaient pas mon intention initiale, j'ai essayé uniquement de construire des jeux d'instructions d'architectures majeures décrites sur Internet, mais sans consulter les documentations des fabricants. Les architectures AMD ne me semblent pas du tout fiables (à l'exception des jeux d'instructions comme 3DNow! Et SSE5). Cependant, j'ai décidé de laisser ici le code des jeux d'instructions de diverses architectures pour que quelqu'un d'autre puisse l'examiner, le corriger / l'améliorer et donner aux autres quelques résultats provisoires.Début du fichier principal nommé
opcode
:Un exemple de
Opcode_list
fichier généré et modifié à l'aide des instructionsopcode
du 27 octobre 2014 est disponible à l' adresse http://pastebin.com/yx4rCxqs . Vous pouvez insérer ce fichier directementopcode
à la place de lasource Opcode_list
ligne. J'ai sorti ce code parce que Stack Exchange ne me permettait pas d'envoyer une réponse aussi importante.Enfin, le reste du
opcode
fichier avec la logique réelle:Veuillez noter que si votre requête de recherche est trop volumineuse (par exemple, avec le jeu d'instructions Haswell et le
-r
commutateur - cela inclut des centaines d'instructions), le calcul peut se poursuivre lentement et prendre beaucoup de temps sur de grandes entrées auxquelles ce script simple n'était pas destiné. .Pour des informations détaillées sur l'utilisation, consultez
Le
opcode
script complet (avec Opcode_list inclus) peut être trouvé à http://pastebin.com/A8bAuHAP .N'hésitez pas à améliorer l'outil et à corriger les erreurs que j'ai pu commettre. Enfin, je voudrais remercier Jonathan Ben-Avraham pour sa grande idée d'utiliser le
gas.vim
fichier de Shirk .EDIT: Le script est maintenant capable de trouver à quel jeu d'instructions appartient un code d'opération (une expression régulière peut être utilisée).
la source
Décompilez d'abord votre binaire:
Recherchez ensuite toutes les instructions SSE4 dans le fichier d'assemblage:
(Remarque: CRC32 peut correspondre aux commentaires.)
Trouvez les instructions AVX les plus courantes (y compris scalaire, y compris AVX2, famille AVX-512 et certains FMA comme
vfmadd132pd
):REMARQUE: testé avec
gawk
etnawk
.la source
Malheureusement, il ne semble pas y avoir d'utilitaire bien connu à ce jour qui détecte le jeu d'instructions requis à partir d'un exécutable donné.
Le mieux que je puisse suggérer pour x86 est d'utiliser
objdump -d
sur le binaire ELF pour désassembler les sections exécutables dans le langage Gnu Assemply (gas
). Ensuite , utilisez de Shirkvim
définitions de syntaxe soitgrep
dans le fichier de code assembleur ou explorer visuellement les code assembleur pour l' une desgasOpcode_SSE41
ou desgasOpcode_SANDYBRIDGE_AVX
instructions que vous voyez dans le polythéisme degas.vim
fichier.Le fichier en langage assembleur contient les instructions au niveau de la machine ("opcodes") que le compilateur a générées lors de la compilation du programme. Si le programme a été compilé avec des indicateurs de compilation pour les instructions SSE ou AVX et que le compilateur a émis des instructions SSE ou AVX, vous devriez voir un ou plusieurs opcodes SSE ou AVX dans la liste de désassemblage produite par
objdump -d
.Par exemple, si vous le faites
grep vroundsdb
sur le fichier de code d'assembly et trouvez une correspondance, vous savez que le fichier binaire nécessite des capacités AVX pour s'exécuter.Il y a pas mal d'instructions spécifiques à la sous-architecture pour x86, comme vous pouvez le voir dans le
gas.vim
fichier de Shirk , doncgrep
ping pour tous les opcodes pour chaque sous-architecture serait certes fastidieux. Écrire un programme C, Perl ou Python pour ce faire pourrait être une excellente idée pour un projet Open Source, surtout si vous pouviez trouver quelqu'un pour l'étendre pour ARM, PPC et d'autres architectures.la source
gas.vim
. OTOH s'il s'agit d'un problème ponctuel, vous pouvez facilement apprendre les modèles des opcodes qui différencient les sous-architectures.J'ai donné à écrire un script utilitaire python basé sur les réponses de Jonathan Ben-Avrahams et Kyselejsyrečeks. C'est un script grossier mais fait le travail.
https://gist.github.com/SleepProgger/d4f5e0a0ea2b9456e6c7ecf256629396 Il télécharge et convertit automatiquement le fichier gas.vim et prend en charge le vidage de toutes les opérations utilisées (facultatives non basiques), y compris l'ensemble de fonctionnalités dont elles proviennent. De plus, il prend en charge la recherche d'op pour l'ensemble de fonctionnalités.
la source