Comment profiler une fonction C ++ au niveau de l’assemblage?

J’ai une fonction qui constitue le goulot d’étranglement de mon programme. Il ne nécessite aucun access à la mémoire et ne nécessite que des calculs. C’est la boucle interne et appelée plusieurs fois, donc tout petit gain pour cette fonction est un gros gain pour mon programme.

Je viens d’un contexte d’optimisation du code SPU sur la PS3 où vous prenez un programme SPU et l’exécutez via un parsingur de pipeline où vous pouvez placer chaque instruction d’assemblage dans sa propre colonne et minimiser le nombre de cycles pris par la fonction. Ensuite, vous superposez des boucles pour minimiser encore davantage les dépendances de pipeline. Avec ce programme et une liste de tous les cycles que chaque instruction d’assemblage prend, je pourrais optimiser beaucoup mieux que le compilateur pourrait jamais.

Sur une autre plate-forme, il y avait des événements que je pouvais enregistrer (échecs, cycles de cache, etc.) et je pouvais exécuter la fonction et suivre les événements du processeur. C’était très bien aussi.

Je fais maintenant un projet de loisir sous Windows en utilisant Visual Studio C ++ 2010 avec un processeur Core i7 Intel. Je n’ai pas l’argent pour justifier le coût élevé de VTune.

Ma question:

Comment profiler une fonction au niveau de l’assemblage pour un processeur Intel sous Windows?

Je veux comstackr, visualiser le désassemblage, obtenir des mesures de performance, ajuster mon code et répéter.

Il existe d’excellents outils gratuits, principalement le CodeAnalyst d’AMD (d’après mon expérience sur mon i7 vs mon phénomène II, c’est un peu handicapé par le processeur Intel car il n’a pas access aux compteurs spécifiques au matériel, bien que cela aurait pu être mauvaise config).

Cependant, un outil moins connu est l’ parsingur de code Intel Architecture (qui est gratuit comme CodeAnalyst), similaire à l’outil spu que vous avez décrit, car il précise la latence, le débit et la pression des ports la même chose) ligne par ligne pour l’assemblage de vos programmes. Stan Melax a donné une belle discussion à ce sujet et sur l’optimisation x86 de cette année, sous le titre “Hotspots, flops and uops: optimisation du processeur vers le métal”.

Intel a également quelques outils de plus dans la même veine que IACA, sous la section optimisation des performances de leur site de code expérimental / what-if , comme PTU, qui est (ou était) une évolution expérimentale de VTune, à partir de ce que je peux. voir, c’est gratuit.

C’est aussi une bonne idée d’avoir lu le manuel d’optimisation d’Intel avant de plonger dans cela.

EDIT: comme Ben l’a fait remarquer, les timings peuvent ne pas être corrects pour les processeurs plus anciens, mais cela peut facilement être compensé par l’utilisation des manuels d’optimisation d’Agner Fog , qui contiennent également de nombreux autres joyaux.

Vous pourriez vouloir essayer certains des utilitaires inclus dans valgrind comme callgrind ou cachegrind.

Callgrind peut effectuer le profilage et l’assemblage de vidage.

Et kcachegrind est une bonne interface graphique, et montrera les vidages, y compris l’assemblage et le nombre de hits par instruction, etc.

De votre description, il semblerait que votre problème puisse être embarrassant , avez-vous envisagé d’utiliser parallel_for ?