MT5 e velocidade em ação - página 45

 
Andrey Khatimlianskii:

Não, eu tenho virtualizadores girando no CentOS. Mas eu não sou competente para continuar este diálogo.

De qualquer forma, é uma dupla virtualização.

CentOS -> VirtualBox -> Windows 7


Também o corte para 2 núcleos quando a CPU está em 8, muda drasticamente o comportamento e os recursos alocados ao threadsheduler.

Estes 2 núcleos terão que ser alocados para os inevitáveis 1000 fios, mesmo com Windows 7 truncado. Assim, é garantido que o terminal tem maior latência.

 
Renat Fatkhullin:

Bem, você é um mestre em testes de estresse de corrida sem controle para correlação e razoabilidade.

É claro que a medição de microssegundos requer recursos para poder medir intervalos de 1000 vezes menos do que um milissegundo.

Se ocasionalmente você precisar medir intervalos com super precisão, então use microssegundos. E isso lhe custará 0 microssegundo.

Como você usa os microssegundos quando são eles que o estão atrasando?! Aqui está um total de 20 chamadas. Um quarto de milissegundo em um número tão ridículo de chamadas para várias tarefas práticas.

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.

Em um VPS asfixiado, o overclocking do temporizador do sistema via timeBeginPeriod está repleto de perigos. Você simplesmente aumentará as despesas gerais da CPU:

Caso contrário, há muito tempo você teria feito GetTickCount/GetTickCount64 precisa no sistema operacional e se regozijaria com a precisão gratuita. Mas não, você terá que pagar pela precisão deste temporizador.


GetTickCount não é de forma alguma inferior em velocidade. Passou a usá-lo em um VPS lento em vez de GetMicrosecondsCount. A carga caiu de 50% para 2% em um comércio 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:

Como usar microssegundos quando são eles que estão diminuindo a velocidade?! Aqui estão apenas 20 chamadas. Um quarto de milissegundo em um número tão ridículo de chamadas para várias tarefas práticas.

E eu tenho estas 20 chamadas:

   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 não é de forma alguma inferior em velocidade. Passou a usá-lo em um VPS lento em vez de GetMicrosecondsCount. A carga caiu de 50% para 2% em um comércio real.

Não acredito que a substituição de GetMicrosecondsCount -> GetTickCount ceda em um programa real. Tanto em teoria como na prática não há provas.

Em um teste de estresse sobre estas duas funções, você pode facilmente desenhar tal resultado. Você mesmo está concluindo que 48% da carga da CPU foi medida por microssegundos? E isto não é um teste de estresse? É claro que sim.


Sobre a aceleração do temporizador multimídia - isto é, testes de estresse novamente sem olhar para a degradação geral do desempenho. O overclocking do embaralhador de tarefas aumenta a sobrecarga do sistema do sistema operacional.

 
Renat Fatkhullin:

Ainda com dupla virtualização.

CentOS -> VirtualBox -> Windows 7


Também cortar para 2 núcleos quando a CPU está em 8, muda drasticamente o comportamento e os recursos alocados ao threadsheduler.

Estes 2 núcleos terão que ser alocados para os inevitáveis 1000 fios, mesmo com Windows 7 truncado. Assim, é garantido que o terminal tem maior latência.

Também cheguei a essa conclusão, obrigado pela confirmação.A VirtualBox é má.
E especialmente cuidado com os vps, em tal implantação, há muitos deles.
Somente sistema operacional puro em hardware, e de preferência Linux.
Embora através do vinho, a mesma virtualização, mas GUI de terminal apenas voa sem um único atraso.
E GetMicrosecondsCount rola sem nenhum atraso.

 
Renat Fatkhullin:

E eu tenho estas 20 chamadas:

Bem, isso também é zero microssegundos para mim! Somente na minha máquina de casa.

Eu não acredito que substituir GetMicrosecondsCount -> GetTickCount seja suficiente em um programa real. Tanto em teoria como na prática não há provas.

No teste de estresse, você pode facilmente extrair tais erros usando estas duas funções. Você mesmo está concluindo que 48% da carga da CPU foi medida por microssegundos? E isto não é um teste de estresse? É claro que sim.

Este tópico me levou a escrever uma biblioteca de referência para que eu pudesse simplesmente inserir uma verificação de tempo de execução na fonte. E aproveitou isso amplamente, revelando e eliminando muitas coisas ruins.

Assim, o Expert Advisor escrito com tal modificação (mais precisamente 20 EAs em paralelo) afeta o computador doméstico em 1,5%. Mas o VPS é 50+%. Quando comecei a escavar, vi que o temporizador de microssegundos estava diminuindo a velocidade. De forma correspondente, onde não foram gerados alertas nas máquinas domésticas, o VPS falha.


Mas mesmo isso não foi suficiente. Graças a este ramo, foi desenvolvido um mecanismo de instantâneos, cuja base é esta.

  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 é a base de todos os instantâneos: se passou menos do que o tempo especificado desde o último instantâneo, não fazemos nada. É esta abordagem que lhe permite economizar significativamente em recursos.

Naturalmente, o tempo de atualização é curto - por padrão, é de um milissegundo. É por isso que é utilizado um timer de microssegundo.


A lentidão deste temporizador causou o colapso do mecanismo de instantâneo, uma vez que foi necessário um instantâneo completo de uma ordem/duas vezes, tanto quanto em uma máquina completa.


Estas são as tortas dos freios temporizados de microssegundo. Mas quando mudei para timer de milissegundos (ao invés de 16ms), tudo começou a voar, mesmo em VPS lento.

Sobre a aceleração do temporizador multimídia - são novamente testes de estresse sem considerar a degradação geral do desempenho. O overclocking do taskmaster aumenta a sobrecarga do sistema do sistema operacional.

Quem se importa com estas teorias quando na prática os ganhos são colossais. Talvez, isso afete alguns jogos. Mas no VPS foi uma palhinha de salvação.

 
fxsaber:

Portanto, para mim também é zero microssegundos! Somente na minha máquina de casa.

Este tópico me levou a escrever uma biblioteca de referência para que eu pudesse simplesmente inserir uma verificação de tempo de execução na fonte. E tirou proveito disso de forma bastante ampla, revelando e eliminando muitas coisas ruins.

Assim, o Expert Advisor escrito de tal forma (mais precisamente 20 Expert Advisors em paralelo) carrega um computador doméstico em 1,5%. Mas o VPS é 50+%. Quando comecei a escavar, vi que o temporizador de microssegundos estava diminuindo a velocidade. De forma correspondente, onde não foram gerados alertas nas máquinas domésticas, o VPS falha.


Mas mesmo isso não foi suficiente. Graças a este ramo, foi desenvolvido um mecanismo de instantâneos, cuja base é esta.

Esta é a base de todos os instantâneos: se passou menos do que o tempo especificado desde o último instantâneo, não fazemos nada. É esta abordagem que lhe permite economizar significativamente em recursos.

Naturalmente, o tempo de atualização é curto - por padrão é de um milissegundo. É por isso que é utilizado um timer de microssegundo.


Assim, devido à lentidão deste temporizador, o mecanismo de instantâneo falhou porque o instantâneo completo foi tirado com muito mais freqüência do que em uma máquina completa.


Esse é o tipo de torta dos freios temporizados de microssegundos. Mas quando mudei para timer de milissegundos (ao invés de 16ms), tudo começou a voar, mesmo em VPS lento.

Eu não me importo com essas teorias, desde que os benefícios práticos sejam enormes. Talvez isso afete alguns jogos. Mas no VPS foi uma palhinha de salvação.

Veja como foi dito de forma bonita:

Passou a usá-lo em um VPS lento em vez de GetMicrosecondsCount. A carga caiu de 50% para 2% no comércio real.

A conclusão era inevitável "tudo por causa dos microssegundos de medição de freios, isso é o que é acelerar".

E de repente acontece que "eu mesmo fiz cálculos uma ordem de grandeza maior devido a um erro lógico". E GetMicrosecondsCount foi apenas um gatilho para este erro.

O retrabalho para GetTickCount é uma correção/crack para este erro e o código da correção não foi mostrado. Porque não é apenas a substituição do GetMicrosecondsCount -> GetTickCount?

Por que não poderia ter sido dito de imediato?


A lógica sugere que a aceleração foi obtida através do bootstrapping explícito da contabilidade (saltando de microssegundos para milissegundos) e reduzindo a criação de instantâneos por um múltiplo.
 
Ainda estou pensando se devo fotografar o SymbolInfoTick para evitá-lo.
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.

Isto é em uma máquina que tritura 20 EAs com 1,5% de CPU. O que a LatencyMon mostra que tudo está bem.

Algo na arquitetura MT5 está dando estes atrasos a todos os EAs em funcionamento ao mesmo tempo. E nenhuma para mim.

 
Renat Fatkhullin:

A conversão para GetTickCount é uma correção/crack para este bug, e o código de correção não foi mostrado. Porque não é apenas a substituição do GetMicrosecondsCount -> GetTickCount?

Por que não poderia ter sido dito de imediato?

As discussões comigo, no entanto, se distinguem pela presença do que é mostrado. Nada é escondido, pelo contrário, é publicado abertamente.

Há certamente um teste de estresse. Não havia outra maneira de mostrá-lo visualmente.


Imagine uma função na forma de uma boneca matryoshka. É feita uma medição da matryoshka externa. Ao mesmo tempo, também são feitas medições do boneco de nidificação interno. Como resultado, devido à frenagem de microssegundos, os bonecos aninhados externos mostram figuras selvagens em seus tempos de execução, o que causa uma onda de Alertas de um tipo. Obviamente, 10 microssegundos para uma chamada para GetMicrosecondsCount é terrivelmente caro. Então eu apressei os alertas.


O temporizador gratuito de milissegundos em bruto começou a dar 0µs, 1000µs ou 2000µs. Isto reduziu muito o número de alertas e reduziu a frenagem nas chamadas de função do timer.


A julgar pela lógica, a aceleração foi obtida através do bootstrapping explícito da contabilidade (pulando de microssegundos para milissegundos) e reduzindo a criação de instantâneos por um múltiplo.


E com instantâneos, é ótimo. O loadout, comparado com a máquina doméstica (microssegundos lá), não é grande. Mas se você comparar com o que estava no VPS, é como o céu e a terra.


ZZY Estamos agora falando sobre a viabilidade de ter em MQL um timer de milissegundos, que, infelizmente, não existe. Não se pode fotografar o VPS sem ele.

 
fxsaber:
Ainda estou considerando a foto do SymbolInfoTick para evitar este tipo de coisas.

Isto é em uma máquina que tritura 20 EAs a 1,5% de CPU. O que a LatencyMon mostra que tudo está bem.

Algo na arquitetura MT5 está dando estes atrasos a todos os EAs em funcionamento ao mesmo tempo. E nenhuma para mim.

Aqui está meu código e tempo de resposta estável: sem centenas ou milhares de microssegundos em 20 gráficos em 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


Quantos núcleos você tem e que tipo de processador? i7-2600?

Outro teste de estresse oculto com milhões de pedidos em paralelo?


Seja mais transparente. Só porque você postou um par de chamadas _B simples não é prova de suas outras reivindicações. Você esquece abruptamente o código e a descrição real das condições, assim que faz reivindicações inusitadas.

Você não precisa imaginar nada em sua mente - contar e mostrar o que você realmente chama e testar. Não um resultado arrancado de "ter feito um teste de estresse desconhecido e esperar por um alerta para mostrar ao mundo", mas exatamente o código completo do teste.

Há também perguntas sobre a própria biblioteca de medições. Há um monte de coisas desnecessárias, inclusive despesas gerais.

 
fxsaber:

Estamos falando agora da utilidade de ter um timer de milissegundos em MQL, que, infelizmente, não existe. Você não pode fotografar a UPU sem ela.

Existe um temporizador de milissegundos há muito tempo: EventSetMillisecondTimer()

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