Q1: Quels outils utilisez-vous pour le profilage de code (profilage, pas d'analyse comparative)?
Q2: Combien de temps laissez-vous le code s'exécuter (statistiques: combien de pas de temps)?
Q3: Quelle est la taille des boîtiers (si le boîtier tient dans le cache, le solveur est plus rapide de plusieurs ordres de grandeur, mais les processus liés à la mémoire me manqueront)?
Voici un exemple de la façon dont je le fais.
Je sépare le benchmarking (voir combien de temps cela prend) du profilage (identifiant comment le rendre plus rapide). Il n'est pas important que le profileur soit rapide. Il est important qu'il vous dise quoi corriger.
Je n'aime même pas le mot "profilage" car il évoque une image quelque chose comme un histogramme, où il y a une barre de coût pour chaque routine, ou "goulot d'étranglement" car cela implique qu'il n'y a qu'une petite place dans le code qui doit être fixé. Ces deux éléments impliquent une sorte de synchronisation et de statistiques, pour lesquelles vous supposez que la précision est importante. Il ne vaut pas la peine de renoncer à la précision de la synchronisation.
La méthode que j'utilise est la pause aléatoire, et il y a une étude de cas complète et un diaporama ici . Une partie de la vision du monde du goulot d'étranglement du profileur est que si vous ne trouvez rien, il n'y a rien à trouver, et si vous trouvez quelque chose et obtenez un certain pourcentage d'accélération, vous déclarez la victoire et quittez. Les fans du profileur ne disent presque jamais combien d'accélération ils obtiennent, et les publicités ne montrent que des problèmes artificiellement conçus pour être faciles à trouver. Une pause aléatoire trouve les problèmes qu'ils soient faciles ou difficiles. Ensuite, la résolution d'un problème en expose d'autres, de sorte que le processus peut être répété, pour obtenir une accélération composée.
D'après mon expérience à partir de nombreux exemples, voici comment cela se passe: je peux trouver un problème (par une pause aléatoire) et le résoudre, en obtenant une accélération de quelques pour cent, disons 30% ou 1,3x. Ensuite, je peux le faire à nouveau, trouver un autre problème et le résoudre, obtenir une autre accélération, peut-être moins de 30%, peut-être plus. Ensuite, je peux le refaire, plusieurs fois jusqu'à ce que je ne trouve vraiment rien d'autre à réparer. Le facteur d'accélération ultime est le produit courant des facteurs individuels, et il peut être incroyablement grand - des ordres de grandeur dans certains cas.
INSÉRÉ: Juste pour illustrer ce dernier point. Il y a un exemple détaillé ici , avec un diaporama et tous les fichiers, montrant comment une accélération de 730x a été obtenue dans une série de suppressions de problèmes. La première version a pris 2700 microsecondes par unité de travail. Le problème A a été supprimé, ramenant le temps à 1800 et agrandissant le pourcentage des problèmes restants de 1,5 fois (2700/1800). Puis B a été retiré. Ce processus s'est poursuivi en six itérations, entraînant une accélération de près de 3 ordres de grandeur. Mais la technique de profilage doit être vraiment efficace, car si aucun de ces problèmes n'est trouvé, c'est-à-dire si vous atteignez un point où vous pensez à tort que rien de plus ne peut être fait, le processus s'arrête.
INSÉRÉ: Pour le dire autrement, voici un graphique du facteur d'accélération total à mesure que les problèmes successifs sont supprimés:
Donc, pour Q1, pour l'analyse comparative, un simple temporisateur suffit. Pour le "profilage", j'utilise une pause aléatoire.
Q2: Je lui donne suffisamment de charge de travail (ou je mets simplement une boucle autour de lui) afin qu'il fonctionne suffisamment longtemps pour faire une pause.
Q3: par tous les moyens, donnez-lui une charge de travail réaliste pour ne pas manquer les problèmes de cache. Ceux-ci apparaîtront comme des exemples dans le code faisant les récupérations de mémoire.