Acerca del perfilador de código de MT5

 

He empezado a utilizar un nuevo perfilador. En esta sección podríamos centralizar la información sobre cómo utilizarla correctamente.

Para empezar tengo algunas preguntas sobre cosas extrañas sobre los datos devueltos por el profiler.

El informe de perfiles que se utiliza en un EA que se ejecuta con datos 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 Perfilador MQL5 982065 marcos de función totales encontrados (279627 código mql5, 122460 incorporado,571051 otro, 8927 sistema)

Resultados (Funciones por llamada):

Q1. El informe dice 139098 mediciones, pero OnTick () Total CPU es 150026, ¿cómo es posible? (pero CopyHistoryData 80087 como 57,58% correctamente significa 100% = 139098).

Q2. El informe dice que hay otras 571.051 "funciones". ¿Qué son estas funciones si no son funciones de mql, incrustadas o del sistema?

Q3. CopyHistoryData muestra 80087 CPU total, con 3 llamadas a funciones reportadas (CopyHigh, CopyLow, CopyTime) que tienen diferente CPU total, ok. Sin embargo, la CPU nativa para estas funciones es la misma e igual a la CPU total (pila de llamadas). Esto parece ser incorrecto ya que en 80087 (pilas) para CopyHistoryData la suma para 3 funciones es de 62.161 (44286 + 9448 + 8427), ¿cómo puede ser que con 62.161 llamadas revele 80.087 pausas en estas 3 funciones? Imposible, la única explicación es que este número es global para CopyHistoryData y por lo tanto inútil. ¿Me estoy perdiendo algo?

 

prueba de espalda se ejecuta en:

2021.07.10 08:00: 37.101 Core 01 EURUSD, H1: 230861 ticks, 998 barras generadas. La prueba se ha superado en 0: 03: 09,367 (incluyendo el preprocesamiento de los ticks 0: 00: 00,515).

He añadido código para medir el tiempo de ejecución de SymbolInfoTick () utilizando 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 Ejecutado = 836973 en 661874 microsegundos

Así, SymbolInfoTick () tardó un total de 661 milisegundos en los datos históricos en 3 minutos y 9 segundos. Sin embargo, el perfilador muestra que utiliza el 74,71% de las medidas. No entiendo hasta qué punto esto es preciso o útil.

 

Otro ejemplo de datos extraños.

Según las estadísticas globales, SymbolInfoTick () estuvo en la pila de llamadas 209 veces. Pero dentro del código, dice 210. Buena precisión.

Según las estadísticas globales, SymbolInfoTick se muestrea 209 veces (lo que supone el 0,83% de todas las muestras). BIEN. Ahora los datos del código dicen que lo alcanza 1 vez (que ahora es el 1,49%, así que si se mira el otro total, ¿cuál es?). Una vez calculado, 1 que equivale al 1,49% significa que la cantidad total (100%) es 67. Así, el 1,49% se refiere a OnTimer (), que es la función principal en este caso. Pero, ¿cómo puede haber 1 allí y 209 en las estadísticas globales?

Incluso si no es un error, ¿cómo puede ser rápidamente útil (lo que debería ser un perfilador, en mi opinión)?

 

Otro más

Esta es una línea de código sobre SymbolInfoTick (), como se mostró anteriormente. ¡Así, una asignación como newTick = false fue "seleccionada" 5 veces! ¿Otras 5 veces después de llamar a SymbolInfoTick () ( 1 - 1.49%)? Bromas aparte...

 
Debe ser un error, contacta con el servicio técnico.
 

Pregúntese qué es y cuál es la diferencia:

  • Perfiles basados en el muestreo (como los que tenemos ahora, similares a los de Visual Studio C++ y otros)
  • Perfiles basados en herramientas de código (como solíamos hacer)

 
Renat Fatkhullin :

Pregúntese qué es y cuál es la diferencia:

  • Perfiles basados en el muestreo (como los que tenemos ahora, similares a los de Visual Studio C++ y otros)
  • Perfilado basado en la instrumentación del código (como teníamos antes)

La diferencia es evidente.

El problema es utilizarlo en la práctica con datos incoherentes y errores.

 
Alain Verleyen:

Otro ejemplo de datos extraños.

Según las estadísticas globales, SymbolInfoTick () estuvo en la pila de llamadas 209 veces. Pero dentro del código, dice 210. Buena precisión.

Según las estadísticas globales, SymbolInfoTick se muestrea 209 veces (lo que supone el 0,83% de todas las muestras). DE ACUERDO. Ahora los datos del código dicen que lo alcanza 1 vez (que ahora es el 1,49%, así que si se mira el otro total, ¿cuál es?). Una vez calculado, 1 que equivale al 1,49% significa que la cantidad total (100%) es 67. Así, el 1,49% se refiere a OnTimer (), que es la función principal en este caso. Pero, ¿cómo puede haber 1 allí y 209 en las estadísticas globales?

Incluso si no es un error, ¿cómo puede ser rápidamente útil (lo que debería ser un perfilador, en mi opinión)?

La captura de pantalla muestra las estadísticas de la cadena de llamada, no la función SymbolInfoTick.

En total, la cadena dada se midió 210 veces, una vez que había un "stop" exactamente en la cadena, antes de la llamada de SymbolInfoTick o justo después, y 209 veces como la cadena de retorno de SymbolInfoTick

 
Alain Verleyen:

Otro más

Esta es una línea de código sobre SymbolInfoTick (), como se mostró anteriormente. ¡Así, una asignación como newTick = false fue "seleccionada" 5 veces! ¿Otras 5 veces después de llamar a SymbolInfoTick () ( 1 - 1.49%)? Bromas aparte...

No entiendo bien lo que está escrito.

Para leer esta captura de pantalla: la cadena fue "detenida" 5 veces, del total de la carga esto es 0.06%, para el código de la función a la que pertenece la cadena esto es 7.46%


 

El contador "Auto CPU" muestra el efecto del código de la cadena en la velocidad de la función en la que se encuentra la cadena.
Es importante destacar que el tiempo de la función llamada en la cadena no es contado por este contador, tal vez esto es incorrecto, vamos a pensar.


El contador "Total CPU" muestra el efecto del código de la cadena en todo el programa, y este contador tiene en cuenta las funciones llamadas en la cadena.

 
Ilyas :

No entiendo bien lo que está escrito.

La forma de leer esta captura de pantalla es la siguiente: la línea está "parada" 5 veces, del total de la carga es el 0,06%, para el código de función al que pertenece la línea es el 7,46%


Sí, lo sé. (Perdón por mi tono anterior, me he enfadado un poco).

El problema es :

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

hasta ahora

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

La CPU general está bien.

Pero en cuanto a Self CPU, ¿cómo es posible que "newTick = false" sea igual a 5 y una llamada a una función como SymbolInfoTick () sea igual a sólo 1? No tiene sentido para mí.