MT5 y la velocidad en acción - página 45

 
Andrey Khatimlianskii:

No, tengo virtualizadores girando en CentOS. Pero no soy competente para continuar este diálogo.

De todos modos, es una doble virtualización.

CentOS -> VirtualBox -> Windows 7


Además, reducir a 2 núcleos cuando la CPU está a 8, cambia drásticamente el comportamiento y los recursos asignados del threadsheduler.

Estos 2 núcleos tendrán que ser asignados a los inevitables 1000 hilos incluso con Windows 7 truncado. Por lo tanto, se garantiza que el terminal tenga una mayor latencia.

 
Renat Fatkhullin:

Bueno, eres un maestro de las pruebas de esfuerzo sin controlar la correlación y la razonabilidad.

Por supuesto, la medición de microsegundos requiere recursos para poder medir intervalos de 1000 veces menos que un milisegundo.

Si de vez en cuando necesitas medir intervalos con mucha precisión, utiliza microsegundos. Y le costará 0 microsegundos.

¿Cómo se usan los microsegundos cuando son lo que te retrasa? Aquí hay un total de 20 llamadas. Un cuarto de milisegundo en un número tan ridículo de llamadas para diversas tareas prácticas.

2020.10.06 00:50:44.491 Alert: Time[Test6.mq5 15: for(inti=0;i<20;i++)GetMicrosecondCount();] = 254 mсs.
2020.10.06 00:50:44.491 Alert: Time[Test6.mq5 20: for(inti=0;i<20;i++)GetTickCount();] = 19 mсs.

En un VPS asfixiado, el overclocking del temporizador del sistema a través de timeBeginPeriod está lleno de peligro. Simplemente aumentará la sobrecarga de la CPU:

De lo contrario, hace tiempo que habrías hecho que GetTickCount/GetTickCount64 fuera preciso en el sistema operativo y te habrías alegrado de la precisión gratuita. Pero no, tendrás que pagar por la precisión de este temporizador.


GetTickCount no es inferior en velocidad. Cambié a usarlo en un VPS lento en lugar de GetMicrosecondsCount. La carga ha bajado del 50% al 2% en una operación real.

2020.10.06 00:50:44.491 Alert: Time[Test6.mq5 26: for(inti=0;i<20;i++)winmm::timeGetTime();] = 13 mсs.
 
fxsaber:

¿Cómo se usan los microsegundos cuando son los que se ralentizan? Aquí hay sólo 20 llamadas. Un cuarto de milisegundo en un número tan ridículo de llamadas para diversas tareas prácticas.

Y tengo estas 20 llamadas:

   ulong ticks=GetMicrosecondCount();
   for(int i=0; i<20; i++)
      GetMicrosecondCount();
   Print("GetMicrosecondCount: ",GetMicrosecondCount()-ticks);

   ticks=GetMicrosecondCount();
   for(int i=0; i<20; i++)
      GetTickCount();
   Print("GetTickCount: ",GetMicrosecondCount()-ticks);


2020.10.06 01:04:44.068 5555 (CAT.NYSE,M5)      GetMicrosecondCount: 1
2020.10.06 01:04:44.068 5555 (CAT.NYSE,M5)      GetTickCount: 0


GetTickCount no es inferior en velocidad. Cambié a usarlo en un VPS lento en lugar de GetMicrosecondsCount. La carga ha bajado del 50% al 2% en una operación real.

No creo que reemplazar GetMicrosecondsCount -> GetTickCount dé en un programa real. Tanto en la teoría como en la práctica no hay pruebas.

En una prueba de esfuerzo sobre estas dos funciones, se puede obtener fácilmente este resultado. ¿Concluye usted mismo que el 48% de la carga de la CPU se midió por microsegundos? ¿Y esto no es una prueba de estrés? Por supuesto que sí.


En cuanto a la aceleración del temporizador multimedia, se trata de nuevo de pruebas de estrés sin tener en cuenta la degradación del rendimiento general. El overclocking del barajador de tareas aumenta la sobrecarga del sistema operativo.

 
Renat Fatkhullin:

Todavía la virtualización dual.

CentOS -> VirtualBox -> Windows 7


Además, reducir a 2 núcleos cuando la CPU está a 8, cambia drásticamente el comportamiento y los recursos asignados del threadsheduler.

Estos 2 núcleos tendrán que ser asignados a los inminentes 1000 hilos incluso con el Windows 7 truncado. Por lo tanto, se garantiza que el terminal tenga una mayor latencia.

Yo también he llegado a esa conclusión, gracias por la confirmación.VirtualBox es malvado.
Y sobre todo cuidado con los vps, en un despliegue así, hay muchos.
Sólo sistema operativo puro en hardware, y preferiblemente Linux.
Aunque a través de wine, misma virtualización, pero la GUI del terminal simplemente vuela sin un solo lag.
Y GetMicrosecondsCount rueda sin ningún retraso.

 
Renat Fatkhullin:

Y tengo estas 20 llamadas:

Bueno, ¡también son cero microsegundos para mí! Sólo en mi máquina doméstica.

No creo que reemplazar GetMicrosecondsCount -> GetTickCount sirva en un programa real. Tanto en la teoría como en la práctica no hay pruebas.

En la prueba de esfuerzo, se pueden extraer fácilmente estos errores utilizando estas dos funciones. ¿Concluye usted mismo que el 48% de la carga de la CPU se midió en microsegundos? ¿Y esto no es una prueba de estrés? Por supuesto que sí.

Este hilo me impulsó a escribir una biblioteca de Benchmark para poder insertar simplemente una comprobación en tiempo de ejecución en la fuente. Y lo aprovechó bastante, revelando y eliminando muchas cosas malas.

Por lo tanto, el Asesor Experto escrito con tal modificación (más precisamente 20 EAs en paralelo) afectan a la computadora de casa en un 1,5%. Pero el VPS es del 50+%. Cuando empecé a indagar, vi que el temporizador de microsegundos se está ralentizando. En consecuencia, cuando no se generaron alertas en las máquinas domésticas, el VPS falla.


Pero ni siquiera eso fue suficiente. Gracias a esta rama, se desarrolló un mecanismo de instantáneas, cuya base es ésta.

  ulong Snapshot( const uint &RefreshTime, const MAGIC_TYPE &Magic, bool HistoryInit = false )
  {
    if (SNAPSHOT::SnapshotLifeTime() < RefreshTime)
      return(0);
// ....

  ulong SnapshotLifeTime( void ) const
  {
    static const bool IsTester = ::MQLInfoInteger(MQL_TESTER);

    return(IsTester ? ULONG_MAX : (::GetMicrosecondCount() - this.TimeData)); // Обязуем любой вызов снепшота в Тестере делать полноценным.
  }

Esta es la base de todas las instantáneas: si ha pasado menos del tiempo especificado desde la última instantánea, no hacemos nada. Este enfoque le permite ahorrar considerablemente en recursos.

Por supuesto, el tiempo de actualización es corto: por defecto es de un milisegundo. Por eso se utiliza un temporizador de microsegundos.


La lentitud de este temporizador hizo que el mecanismo de instantáneas se colapsara, ya que tomaba una instantánea completa un orden/dos veces más a menudo que en una máquina completa.


Así son las tartas de los frenos del temporizador de microsegundos. Pero cuando cambié al temporizador de milisegundos (en lugar de 16ms), todo empezó a volar, incluso en el VPS lento.

En cuanto a la aceleración del temporizador multimedia, se trata de nuevo de pruebas de estrés sin tener en cuenta la degradación del rendimiento general. El overclocking del taskmaster aumenta la sobrecarga del sistema operativo.

A quién le importan estas teorías cuando en la práctica las ganancias son colosales. Tal vez, afecte a algunos partidos. Pero en VPS fue una paja salvadora.

 
fxsaber:

¡Bueno, para mí también son cero microsegundos! Sólo en mi máquina doméstica.

Este hilo me impulsó a escribir una biblioteca de Benchmark para poder insertar una comprobación en tiempo de ejecución en el código fuente. Y lo aprovechó bastante, revelando y eliminando muchas cosas malas.

Por lo tanto, el Asesor Experto escrito de tal manera (más precisamente 20 Asesores Expertos en paralelo) carga un ordenador doméstico en un 1,5%. Pero el VPS es del 50+%. Cuando empecé a indagar, vi que el temporizador de microsegundos se está ralentizando. En consecuencia, cuando no se generaron alertas en las máquinas domésticas, el VPS falla.


Pero ni siquiera eso fue suficiente. Gracias a esta rama, se desarrolló un mecanismo de instantáneas, cuya base es ésta.

Esta es la base de todas las instantáneas: si ha pasado menos del tiempo especificado desde la última instantánea, no hacemos nada. Este enfoque le permite ahorrar considerablemente en recursos.

Por supuesto, el tiempo de actualización es corto: por defecto es de un milisegundo. Por eso se utiliza un temporizador de microsegundos.


Por lo tanto, debido a la lentitud de este temporizador, el mecanismo de instantáneas se estrelló porque la instantánea completa se tomó con mucha más frecuencia que en una máquina completa.


Ese es el tipo de tarta de los frenos del temporizador de microsegundos. Pero cuando cambié al temporizador de milisegundos (en lugar de 16ms), todo empezó a volar, incluso en el VPS lento.

No me importan estas teorías, siempre que los beneficios prácticos sean enormes. Tal vez afecte a algunos partidos. Pero en VPS fue una paja salvadora.

Mira que bien lo han dicho:

Cambié a usarlo en un VPS lento en lugar de GetMicrosecondsCount. La carga bajó del 50% al 2% en el comercio real.

La conclusión fue inevitable: "todo por culpa de los microsegundos de medición de los frenos, eso es el aceleramiento".

Y de repente resulta que "yo mismo hice cálculos de un orden de magnitud mayor debido a un error lógico". Y GetMicrosecondsCount sólo era un desencadenante de este error.

El reajuste de GetTickCount es una solución/remedio para este error y el código de la solución no se mostró. ¿Porque no es sólo la sustitución de GetMicrosecondsCount -> GetTickCount?

¿Por qué no se pudo decir de inmediato?


La lógica parece haberse acelerado por el aparente arranque de la contabilidad (saltando de microsegundos a milisegundos) y la reducción múltiple de la creación de instantáneas.
 
Todavía estoy pensando si hacer un snapshot de SymbolInfoTick para evitarlo.
2020.10.05 12:52:35.963         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 599 mсs.
2020.10.05 12:52:45.904         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 245 mсs.
2020.10.05 12:52:45.904         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 470 mсs.
2020.10.05 12:52:45.904         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 722 mсs.
2020.10.05 12:52:45.904         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 901 mсs.
2020.10.05 12:52:45.905         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1726 mсs.
2020.10.05 12:53:00.123         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 864 mсs.
2020.10.05 12:53:03.218         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 112 mсs.
2020.10.05 12:53:04.493         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 2134 mсs.
2020.10.05 12:53:10.013         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1826 mсs.
2020.10.05 12:53:13.119         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 114 mсs.
2020.10.05 12:53:18.008         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 116 mсs.
2020.10.05 12:53:20.010         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1095 mсs.
2020.10.05 12:55:55.033         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 359 mсs.

Esto es en una máquina que muele 20 EAs con 1,5% de CPU. Lo que LatencyMon muestra que todo está bien.

Algo en la arquitectura de MT5 está dando estos retrasos a todos los EAs que se ejecutan al mismo tiempo. Y ninguno para mí.

 
Renat Fatkhullin:

La conversión a GetTickCount es una corrección/revisión de este error, y el código de corrección no se mostró. ¿Porque no es sólo la sustitución de GetMicrosecondsCount -> GetTickCount?

¿Por qué no se pudo decir de inmediato?

Sin embargo, las discusiones conmigo se distinguen por la presencia de lo que se muestra. No se oculta nada, al contrario, se publica abiertamente.

Ciertamente, hay una prueba de estrés. No había otra forma de mostrarlo visualmente.


Imagine una función en forma de muñeca matrioska. Se toma una medida de la matrioska exterior. Al mismo tiempo, se toman las medidas de los muñecos internos del nido. Como resultado, debido al frenado de los microsegundos, los muñecos anidados externos muestran cifras salvajes en sus tiempos de ejecución, lo que provoca una avalancha de Alertas de tipo único. Obviamente, 10 microsegundos por una llamada a GetMicrosecondsCount es terriblemente caro. Así que apuré las alertas.


El temporizador de milisegundos libre comenzó a dar 0µs, 1000µs o 2000µs. Esto redujo en gran medida el número de Alertas y redujo el frenado en las llamadas a las funciones del temporizador.


A juzgar por la lógica, la aceleración se ha obtenido al arrancar explícitamente la contabilidad (saltando de microsegundos a milisegundos) y reduciendo la creación de instantáneas en un múltiplo.


Y con las instantáneas, es genial. La carga, en comparación con la máquina de casa (microsegundos allí), no es grande. Pero si lo comparas con lo que había en VPS, es como el cielo y la tierra.


SZZ ahora estamos hablando de la viabilidad de tener en MQL temporizador de milisegundos, que, por desgracia, no existe. No se puede hacer un snapshot en VPS sin él.

 
fxsaber:
Todavía estoy considerando la instantánea SymbolInfoTick para evitar este tipo de cosas.

Esto es en una máquina que muele 20 EAs al 1,5% de CPU. Lo que LatencyMon muestra que todo está bien.

Algo en la arquitectura de MT5 está dando estos retrasos a todos los EAs que se ejecutan al mismo tiempo. Y ninguno para mí.

Aquí está mi código y el tiempo de ejecución estable: no hay cientos o miles de microsegundos en 20 gráficos en paralelo

   MqlTick Tick;
   ulong   ticks=GetMicrosecondCount();
   
   SymbolInfoTick(_Symbol,Tick);
   Print("SymbolInfoTick: ",GetMicrosecondCount()-ticks);


2020.10.06 02:14:18.234	5555 (CADJPY,H1)	SymbolInfoTick: 2
2020.10.06 02:14:18.765	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:19.063	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:19.180	5555 (CADJPY,H1)	SymbolInfoTick: 2
2020.10.06 02:14:19.180	5555 (EURCAD,H1)	SymbolInfoTick: 1
2020.10.06 02:14:19.245	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:19.523	5555 (CHFJPY,H1)	SymbolInfoTick: 1
2020.10.06 02:14:19.659	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.037	5555 (CADCHF,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.037	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.137	5555 (EURMXN,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.138	5555 (EURNOK,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.226	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.227	5555 (CHFJPY,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.525	5555 (AUDNZD,H1)	SymbolInfoTick: 1
2020.10.06 02:14:20.645	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.919	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:21.123	5555 (EURNZD,H1)	SymbolInfoTick: 1
2020.10.06 02:14:21.129	5555 (EURAUD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:21.234	5555 (EURNOK,H1)	SymbolInfoTick: 1
2020.10.06 02:14:21.441	5555 (EURAUD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:22.299	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:22.383	5555 (AUDNZD,H1)	SymbolInfoTick: 2


¿Cuántos núcleos tiene y qué tipo de procesador? ¿i7-2600?

¿Otra prueba de esfuerzo oculta con millones de peticiones en paralelo?


Sea más transparente. El hecho de que hayas publicado un par de simples llamadas _B no es una prueba de tus otras afirmaciones. Se olvida bruscamente del código y de la descripción real de las condiciones en cuanto hace afirmaciones extravagantes.

No necesitas imaginar nada en tu mente: cuenta y muestra lo que realmente llamas y pruebas. No un resultado arrancado de "ejecutó una prueba de esfuerzo desconocida y espera una alerta para mostrar al mundo", sino exactamente el código completo de la prueba.

También hay preguntas sobre la propia biblioteca de mediciones. Hay muchas cosas innecesarias, incluidos los gastos generales.

 
fxsaber:

Ahora estamos hablando de la utilidad de tener un temporizador de milisegundos en MQL, que, por desgracia, no existe. No se puede hacer una instantánea en la UPU sin ella.

Existe un temporizador de milisegundos desde hace tiempo: EventSetMillisecondTimer()

Документация по MQL5: Работа с событиями / EventSetMillisecondTimer
Документация по MQL5: Работа с событиями / EventSetMillisecondTimer
  • www.mql5.com
Указывает клиентскому терминалу, что для данного эксперта или индикатора необходимо генерировать события таймера с периодичностью менее одной секунды. нужно получать события таймера чаще, чем один раз в секунду. Если вам достаточно обычного таймера с периодом более 1 секунды, то используйте EventSetTimer(). В тестере стратегий используется...