Sobre o profiler do código MT5

 

Comecei a usar um novo perfilador. Nesta seção, poderíamos centralizar as informações sobre como utilizá-las corretamente.

Para começar, tenho algumas perguntas sobre coisas estranhas sobre os dados devolvidos pelo profiler.

O relatório de perfil que é usado em um EA que roda sobre dados históricos:

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 perfilador 982065 quadros funcionais totais encontrados (279627 mql5 código, 122460 embutido,571051 outro, sistema 8927)

Resultados (Funções por chamada):

Q1. O relatório diz 139098 medições, mas OnTick () Total de CPU é 150026, como isso é possível? (mas CopyHistoryData 80087 como 57,58% corretamente significa 100% = 139098).

Q2. O relatório diz 571.051 outras "funções". Quais são essas funções se não são mql, embutidas ou funções do sistema?

Q3. CopyHistoryData mostra a CPU total 80087, com 3 chamadas de funções reportadas (CopyHigh, CopyLow, CopyTime) tendo CPU total diferente, ok. Entretanto, a CPU nativa para estas funções é a mesma e igual à CPU total (pilha de chamadas). Isto parece estar incorreto, pois com 80087 (pilhas) para CopyHistoryData a soma para 3 funções é 62.161 (44286 + 9448 + 8427), como pode ser que com 62.161 chamadas revela 80.087 pausas nestas 3 funções? Impossível, a única explicação é que este número é global para CopyHistoryData e, portanto, inútil. Está me faltando alguma coisa?

 

O backtest funcionando em:

2021.07.10 08:00: 37.101 Core 01 EURUSD, H1: 230861 carrapatos, 998 barras geradas. O teste passou em 0: 03: 09.367 (incluindo o pré-processamento de carrapatos 0: 00: 00.515).

Adicionei código para medir o tempo de execução do SymbolInfoTick () usando GetMicrosecondCount ().

       ulong start= GetMicrosecondCount ();

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

      BENCH += GetMicrosecondCount ()-start;

Resultado:

2021.07.10 08:00: 37.101 Core 01 2021.05.30 23:59:59 Total = 1209572 Executado = 836973 em 661874 microssegundos

Assim, o SymbolInfoTick () levou um total de 661 milissegundos sobre os dados históricos em 3 minutos e 9 segundos. Entretanto, o perfilador mostra que utiliza 74,71% das medidas. Como isto é preciso ou útil, eu não entendo.

 

Outro exemplo de dados estranhos.

De acordo com as estatísticas globais, SymbolInfoTick () esteve na pilha de chamadas 209 vezes. Mas dentro do código, ele diz 210. Boa precisão.

De acordo com as estatísticas globais, o SymbolInfoTick é amostrado 209 vezes (que é 0,83% de todas as amostras). OK. Agora os dados do código dizem que ele chega a ele 1 vez (que agora é 1,49%, então se você olhar para o outro total, o que é?). Uma vez calculado, 1 igual a 1,49% significa que a quantidade total (100%) é 67. Assim, 1,49% se refere ao OnTimer (), que é a função principal neste caso. Mas como pode haver 1 lá e 209 nas estatísticas globais?

Mesmo que não seja um erro, como pode ser rapidamente útil (o que um profiler deve ser, em minha opinião)?

 

Outro

Esta é uma linha de código sobre SymbolInfoTick (), como mostrado anteriormente. Então, uma tarefa como newTick = falso foi "selecionada" 5 vezes! Mais 5 vezes após chamar SymbolInfoTick () ( 1 - 1,49%)? Brincadeiras à parte ?

 
Deve ser um bug, entre em contato com a central de serviço.
 

Pergunte-se o que é e qual é a diferença:

  • Perfil baseado na amostragem (como temos agora, semelhante ao Visual Studio C++ e outros)
  • Perfil com base em ferramentas de código (como costumávamos fazer)

 
Renat Fatkhullin :

Pergunte-se o que é e qual é a diferença:

  • Perfil baseado na amostragem (como temos agora, semelhante ao Visual Studio C++ e outros)
  • Perfilamento baseado em instrumentação de código (como tínhamos antes)

A diferença é óbvia.

O problema é utilizá-lo na prática com dados e erros inconsistentes.

 
Alain Verleyen:

Outro exemplo de dados estranhos.

De acordo com as estatísticas globais, SymbolInfoTick () esteve na pilha de chamadas 209 vezes. Mas dentro do código, ele diz 210. Boa precisão.

De acordo com as estatísticas globais, o SymbolInfoTick é amostrado 209 vezes (que é 0,83% de todas as amostras). OK. Agora os dados do código dizem que ele chega a ele 1 vez (que agora é 1,49%, então se você olhar para o outro total, o que é?). Uma vez calculado, 1 igual a 1,49% significa que o número total (100%) é 67. Assim, 1,49% se refere ao OnTimer (), que é a principal função neste caso. Mas como pode haver 1 lá e 209 nas estatísticas globais?

Mesmo que não seja um erro, como pode ser rapidamente útil (o que um profiler deve ser, em minha opinião)?

A captura de tela mostra as estatísticas da seqüência de chamada, não a função SymbolInfoTick.

No total, a corda dada foi medida 210 vezes, uma vez que houve uma "parada" exatamente na corda, antes da chamada do SymbolInfoTick ou logo após, e 209 vezes como a corda de retorno do SymbolInfoTick

 
Alain Verleyen:

Outro

Esta é uma linha de código sobre SymbolInfoTick (), como mostrado anteriormente. Então, uma tarefa como newTick = falso foi "selecionada" 5 vezes! Outras 5 vezes após chamar SymbolInfoTick () ( 1 - 1,49%)? Brincadeiras à parte ?

Eu não entendo bem o que está escrito.

Para ler esta captura de tela: a string foi "parada" 5 vezes, da carga total isto é 0,06%, para o código da função à qual a string pertence isto é 7,46%.


 

O contador "Self CPU" exibe o efeito do código da string sobre a velocidade da função na qual a string está localizada.
É importante notar que o tempo da função chamada na corda não é contado por este contador, talvez isto esteja errado, vamos pensar.


O contador "CPU Total" mostra o efeito do código da string em todo o programa, e este contador leva em conta as funções chamadas na string.

 
Ilyas :

Eu não entendo bem o que está escrito.

A forma como você deve ler esta captura de tela é esta: a linha está "parada" 5 vezes, da carga total é 0,06%, para o código da função a linha pertence a ela é 7,46%.


Sim, eu sei. (Desculpe pelo meu tom anterior, eu fiquei um pouco irritado).

O problema é :

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

até o momento

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

A CPU geral está bem.

Mas quanto ao Self CPU, como é possível que "newTick = false" seja igual a 5 e uma chamada de função como SymbolInfoTick () seja igual a apenas 1? Isso não faz sentido para mim.