À propos du profileur de code MT5

 

J'ai commencé à utiliser un nouveau profileur. Dans cette section, nous pourrions centraliser les informations sur la manière de l'utiliser correctement.

Pour commencer, j'ai quelques questions sur des choses étranges concernant les données renvoyées par le profileur.

Le rapport de profilage qui est utilisé dans un EA fonctionnant sur des données historiques :

2021.07.08 15:43:06.269  MQL5 profiler 139098  total measurements, 0/0 errors, 320 mb of stack memory analyzed (92848/1073741824)

2021.07.08 15:43:06.269 MQL5 profiler 982065 total function frames found (279627 mql5 code, 122460 built-in,571051 other, 8927 system)

Résultats (Fonctions par appel) :

Q1. Le rapport indique 139098 mesures, mais OnTick () Total CPU est 150026, comment est-ce possible ? (mais CopyHistoryData 80087 comme 57.58% correctement signifie 100% = 139098).

Q2. Le rapport indique 571 051 autres "fonctions". Quelles sont ces fonctions si elles ne sont pas des fonctions mql, embarquées ou système ?

Q3. CopyHistoryData indique 80087 CPU totaux, avec 3 appels de fonctions rapportés (CopyHigh, CopyLow, CopyTime) ayant des CPU totaux différents, ok. Cependant, le CPU natif pour ces fonctions est le même et égal au CPU total (pile d'appels). Cela semble incorrect car à 80087 (piles) pour CopyHistoryData la somme pour 3 fonctions est de 62 161 (44286 + 9448 + 8427), comment se peut-il qu'avec 62 161 appels il détecte 80 087 pauses dans ces 3 fonctions ? Impossible, la seule explication est que ce numéro est global pour CopyHistoryData et donc inutile. Est-ce que j'ai manqué quelque chose ?

 

Backtest en cours à :

2021.07.10 08:00 : 37.101 Core 01 EURUSD, H1 : 230861 ticks, 998 barres générées. Le test a réussi en 0 : 03 : 09.367 (y compris le prétraitement des ticks 0 : 00 : 00.515).

J'ai ajouté du code pour mesurer le temps d'exécution de SymbolInfoTick () en utilisant GetMicrosecondCount ().

       ulong start= GetMicrosecondCount ();

       //--- Get tick information
       if (! SymbolInfoTick (symbol,tick))
         return ( false );

      BENCH += GetMicrosecondCount ()-start;

Résultat :

2021.07.10 08:00 : 37.101 Core 01 2021.05.30 23:59:59 Total = 1209572 Exécuté = 836973 en 661874 microsecondes

Ainsi, SymbolInfoTick () a pris un total de 661 millisecondes sur les données historiques en 3 minutes et 9 secondes. Cependant, le profileur montre qu'il utilise 74,71% des mesures. Je ne comprends pas à quel point c'est précis ou utile.

 

Un autre exemple de données étranges.

Selon les statistiques globales, SymbolInfoTick () a été dans la pile d'appels 209 fois. Mais dans le code, il est écrit 210. Bonne précision.

Selon les statistiques globales, SymbolInfoTick est échantillonné 209 fois (soit 0,83% de tous les échantillons). OK. Maintenant, les données du code indiquent qu'il l'atteint 1 fois (ce qui représente maintenant 1,49%, donc si vous regardez l'autre total, quel est-il ?). Une fois calculé, 1 égal à 1,49% signifie que le nombre total (100%) est 67. Ainsi, 1,49% fait référence à OnTimer (), qui est la fonction principale dans ce cas. Mais comment peut-il y avoir 1 là et 209 dans les statistiques mondiales ?

Même s'il ne s'agit pas d'une erreur, comment cela peut-il être rapidement utile (ce que devrait être un profileur, à mon avis) ?

 

Un autre

Il s'agit d'une ligne de code au-dessus de SymbolInfoTick (), comme indiqué précédemment. Ainsi, une affectation comme newTick = false a été "sélectionnée" 5 fois ! Encore 5 fois après avoir appelé SymbolInfoTick () ( 1 - 1.49%) ? Blagues à part ?

 
Il doit s'agir d'un bug, contactez le service d'assistance.
 

Demandez-vous ce que c'est et quelle est la différence :

  • Profilage basé sur l'échantillonnage (comme nous l'avons actuellement, similaire à Visual Studio C++ et autres)
  • Profilage basé sur l'outillage du code (comme nous le faisions auparavant)

 
Renat Fatkhullin :

Demandez-vous ce que c'est et quelle est la différence :

  • Profilage basé sur l'échantillonnage (comme nous l'avons actuellement, similaire à Visual Studio C++ et autres)
  • Profilage basé sur l'instrumentation du code (comme nous l'avions auparavant)

La différence est évidente.

Le problème est de l'utiliser dans la pratique avec des données incohérentes et des erreurs.

 
Alain Verleyen:

Un autre exemple de données étranges.

Selon les statistiques globales, SymbolInfoTick () a été dans la pile d'appels 209 fois. Mais dans le code, il est écrit 210. Bonne précision.

Selon les statistiques globales, SymbolInfoTick est échantillonné 209 fois (soit 0,83% de tous les échantillons). OK. Maintenant, les données du code indiquent qu'il l'atteint 1 fois (ce qui représente maintenant 1,49%, donc si vous regardez l'autre total, qu'est-ce que c'est ?). Une fois calculé, 1 égal à 1,49% signifie que la quantité totale (100%) est de 67. Ainsi, 1,49% fait référence à OnTimer (), qui est la fonction principale dans ce cas. Mais comment peut-il y avoir 1 là et 209 dans les statistiques mondiales ?

Même si ce n'est pas une erreur, comment cela peut-il être rapidement utile (ce que devrait être un profileur, à mon avis) ?

La capture d'écran montre les statistiques pour la chaîne appelante, pas pour la fonction SymbolInfoTick.

Au total, la chaîne donnée a été mesurée 210 fois, une fois qu'il y avait un "stop" exactement sur la chaîne, avant l'appel de SymbolInfoTick ou juste après, et 209 fois comme chaîne de retour de SymbolInfoTick.

 
Alain Verleyen:

Un autre

Il s'agit d'une ligne de code au-dessus de SymbolInfoTick (), comme indiqué précédemment. Ainsi, une affectation comme newTick = false a été "sélectionnée" 5 fois ! Encore 5 fois après avoir appelé SymbolInfoTick () ( 1 - 1.49%) ? Blagues à part ?

Je n'ai pas bien compris ce qui était écrit.

Pour lire cette capture d'écran : la chaîne a été "arrêtée" 5 fois, sur la charge totale cela représente 0,06%, pour le code de la fonction à laquelle la chaîne appartient cela représente 7,46%.


 

Le compteur "Self CPU" affiche l'effet du code de la chaîne sur la vitesse de la fonction dans laquelle se trouve la chaîne.
Il est important de noter que le temps de la fonction appelée dans la chaîne n'est pas compté par ce compteur, peut-être est-ce une erreur, réfléchissons.


Le compteur "Total CPU" montre l'effet du code de la chaîne sur l'ensemble du programme, et ce compteur prend en compte les fonctions appelées dans la chaîne.

 
Ilyas :

Je ne comprends pas bien ce qui est écrit.

La façon dont vous devez lire cette capture d'écran est la suivante : la ligne est "arrêtée" 5 fois, la charge totale est de 0,06%, pour le code de la fonction à laquelle la ligne appartient, elle est de 7,46%.


Oui, je sais. (Désolé pour mon ton précédent, je me suis un peu énervé).

Le problème est le suivant :

      newTickф  = false ;                     // Total CPU : 5 (0.06%)    Self CPU : 5 (7.46%)

jusqu'à présent

       if (! SymbolInfoTick (symbolф,tickф))     // Total CPU : 210 (2.57%)  Self CPU : 1 (1.49%)

Le processeur général est bon.

Mais en ce qui concerne Self CPU, comment est-il possible que "newTick = false" soit égal à 5 et qu'un appel de fonction comme SymbolInfoTick () ne soit égal qu'à 1 ? Ça n'a pas de sens pour moi.

Raison: