Question

J'essaie de démarrer avec Google Perf Tools pour profiler certaines applications gourmandes en ressources CPU. C'est un calcul statistique qui vide chaque étape dans un fichier en utilisant `ofstream '. Je ne suis pas un expert en C ++, alors j'ai du mal à trouver le goulot d'étranglement. Mon premier passage donne des résultats:

Total: 857 samples
     357  41.7%  41.7%      357  41.7% _write$UNIX2003
     134  15.6%  57.3%      134  15.6% _exp$fenv_access_off
     109  12.7%  70.0%      276  32.2% scythe::dnorm
     103  12.0%  82.0%      103  12.0% _log$fenv_access_off
      58   6.8%  88.8%       58   6.8% scythe::const_matrix_forward_iterator::operator*
      37   4.3%  93.1%       37   4.3% scythe::matrix_forward_iterator::operator*
      15   1.8%  94.9%       47   5.5% std::transform
      13   1.5%  96.4%      486  56.7% SliceStep::DoStep
      10   1.2%  97.5%       10   1.2% 0x0002726c
       5   0.6%  98.1%        5   0.6% 0x000271c7
       5   0.6%  98.7%        5   0.6% _write$NOCANCEL$UNIX2003

Ceci est surprenant, car tout le calcul réel se produit dans SliceStep :: DoStep. Le & Quot; _write $ UNIX2003 & Quot; (Où puis-je savoir ce que c'est?) semble provenir de l'écriture du fichier de sortie. Maintenant, ce qui me dérange, c’est que si je commente toutes les instructions outfile << "text" et exécute pprof, 95% sont dans SliceStep::DoStep et que «_write $ UNIX2003» disparaît. Cependant, mon application ne s’accélère pas, mesurée par le temps total. Le tout accélère moins de 1%.

Qu'est-ce qui me manque?

Ajouté: La sortie de pprof sans les outfile << instructions est:

Total: 790 samples
     205  25.9%  25.9%      205  25.9% _exp$fenv_access_off
     170  21.5%  47.5%      170  21.5% _log$fenv_access_off
     162  20.5%  68.0%      437  55.3% scythe::dnorm
      83  10.5%  78.5%       83  10.5% scythe::const_matrix_forward_iterator::operator*
      70   8.9%  87.3%       70   8.9% scythe::matrix_forward_iterator::operator*
      28   3.5%  90.9%       78   9.9% std::transform
      26   3.3%  94.2%       26   3.3% 0x00027262
      12   1.5%  95.7%       12   1.5% _write$NOCANCEL$UNIX2003
      11   1.4%  97.1%      764  96.7% SliceStep::DoStep
       9   1.1%  98.2%        9   1.1% 0x00027253
       6   0.8%  99.0%        6   0.8% 0x000274a6

Cela ressemble à ce à quoi je m'attendais, sauf que je ne vois aucune augmentation visible de la performance (0,1 seconde sur un calcul de 10 secondes). Le code est essentiellement:

ofstream outfile("out.txt");
for loop:
  SliceStep::DoStep()
  outfile << 'result'
outfile.close()

Mise à jour: Je chronomètre à l’aide de boost :: timer, qui commence au début et à la fin du profileur. Je n'utilise pas de fils ou quoi que ce soit de fantaisie.

Était-ce utile?

La solution

D'après mes commentaires:

Les chiffres fournis par votre profileur indiquent que le programme devrait être environ 40% plus rapide sans les instructions d'impression.

Le temps d’exécution reste toutefois pratiquement identique.

Évidemment, l’une des mesures doit être fausse. Cela signifie que vous devez faire plus et de meilleures mesures.

Tout d'abord, je suggère de commencer avec un autre outil simple: la commande time. Cela devrait vous donner une idée approximative du temps que vous passez.

Si les résultats ne sont toujours pas concluants, vous avez besoin d'un meilleur test:

  • Utiliser un problème plus important
  • Faites un échauffement avant de mesurer. Faites des boucles et commencez les mesures par la suite (dans le même processus).
  

Tiristan: Tout est dans l'utilisateur. Ce que je fais est assez simple, je pense ... Le fait que le fichier soit ouvert tout le temps signifie-t-il quelque chose?

Cela signifie que le profileur a tort.

Si vous imprimez 100 000 lignes sur la console à l’aide de python, vous obtiendrez quelque chose comme:

for i in xrange(100000):
    print i

Pour consoler:

time python print.py
[...]
real    0m2.370s
user    0m0.156s
sys     0m0.232s

Versus:

time python test.py > /dev/null

real    0m0.133s
user    0m0.116s
sys     0m0.008s

Mon point est le suivant: Vos mesures et internes indiquent que vous ne gagnez rien à la désactivation de la sortie. Google Perf Tools dit que vous devriez. Qui a tort?

Autres conseils

_write $ UNIX2003 fait probablement référence à l'appel système write POSIX, qui envoie les données au terminal. Les E / S sont très lentes par rapport à presque tout le reste. Il est donc logique que votre programme passe beaucoup de temps là-bas si vous écrivez pas mal de résultats.

Je ne sais pas pourquoi votre programme n'accélère pas l'accélération lorsque vous supprimez la sortie, mais je ne peux pas vraiment deviner ce que vous avez donné. Ce serait bien de voir une partie du code, voire même la sortie de perftools lorsque l’instruction cout est supprimée.

Google perftools collecte des échantillons de la pile d'appels. Vous avez donc besoin d'obtenir une visibilité sur ceux-ci.

Selon le document, vous pouvez afficher le graphe d'appel avec une granularité d'instruction ou d'adresse. Cela devrait vous dire ce que vous devez savoir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top