MT5 et la vitesse en action - page 45

 
Andrey Khatimlianskii:

Non, j'ai des virtualisateurs qui tournent sous CentOS. Mais je ne suis pas compétent pour poursuivre ce dialogue.

C'est une double virtualisation de toute façon.

CentOS -> VirtualBox -> Windows 7


De même, le fait de réduire à 2 cœurs alors que le CPU en compte 8 modifie radicalement le comportement et les ressources allouées par le threadsheduler.

Ces 2 cœurs devront être alloués aux 1000 threads imminents, même avec le Windows 7 tronqué. Le terminal est donc assuré d'avoir une latence accrue.

 
Renat Fatkhullin:

Vous êtes un maître des tests de stress sans contrôle de la corrélation et du caractère raisonnable.

Bien entendu, le comptage à la microseconde nécessite des ressources pour pouvoir mesurer des intervalles 1 000 fois plus petits qu'une milliseconde.

Si vous avez occasionnellement besoin de mesurer des intervalles avec une grande précision, utilisez les microsecondes. Et cela vous coûtera 0 microseconde.

Comment utiliser les microsecondes quand c'est elles qui vous ralentissent ? ! Voici un total de 20 appels. Un quart de milliseconde sur un nombre aussi ridicule d'appels pour diverses tâches pratiques.

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.

Sur un VPS étouffé, l'overclocking du timer du système via timeBeginPeriod est lourd de danger. Vous augmenterez simplement la surcharge du CPU :

Sinon, vous auriez depuis longtemps rendu GetTickCount/GetTickCount64 précis dans le système d'exploitation et vous vous seriez réjoui de cette précision gratuite. Mais non, vous devrez payer pour la précision de cette minuterie.


GetTickCount n'est en aucun cas inférieur en vitesse. J'ai commencé à l'utiliser sur un VPS lent à la place de GetMicrosecondsCount. La charge est passée de 50% à 2% sur un commerce réel.

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

Comment utiliser les microsecondes quand ce sont elles qui ralentissent ? ! Voici seulement 20 appels. Un quart de milliseconde sur un nombre aussi ridicule d'appels pour diverses tâches pratiques.

Et j'ai ces 20 appels :

   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'est en aucun cas inférieur en vitesse. J'ai commencé à l'utiliser sur un VPS lent à la place de GetMicrosecondsCount. La charge est passée de 50 % à 2 % sur une transaction réelle.

Je ne crois pas que remplacer GetMicrosecondsCount -> GetTickCount donnera dans un vrai programme. Tant sur le plan théorique que pratique, il n'y a aucune preuve.

Dans un test de stress sur ces deux fonctions, vous pouvez facilement obtenir un tel résultat. Vous en concluez vous-même que 48% de la charge du CPU a été mesurée en microsecondes ? Et ce n'est pas un test de stress ? Bien sûr qu'elle l'est.


En ce qui concerne l'accélération du minuteur multimédia, il s'agit encore une fois de tests de stress sans tenir compte de la dégradation globale des performances. L'overclocking du mélangeur de tâches augmente l'overhead du système d'exploitation.

 
Renat Fatkhullin:

Toujours la double virtualisation.

CentOS -> VirtualBox -> Windows 7


De même, le fait de réduire à 2 cœurs alors que le CPU en compte 8 modifie radicalement le comportement et les ressources allouées par le threadsheduler.

Ces 2 cœurs devront être alloués aux 1000 threads imminents, même avec le Windows 7 tronqué. Le terminal est donc assuré d'avoir une latence accrue.

J'en suis arrivé à cette conclusion aussi, merci pour la confirmation.VirtualBox est le mal.
Et surtout méfiez-vous des vps, sur un tel déploiement, il y en a beaucoup.
Uniquement un système d'exploitation pur sur le matériel, et de préférence Linux.
Bien qu'à travers le vin, la même virtualisation, mais l'interface graphique du terminal fonctionne sans le moindre décalage.
Et GetMicrosecondsCount se déroule sans aucun décalage.

 
Renat Fatkhullin:

Et j'ai ces 20 appels :

Eh bien, c'est zéro microseconde pour moi aussi ! Seulement sur mon ordinateur personnel.

Je ne crois pas que remplacer GetMicrosecondsCount -> GetTickCount fera l'affaire dans un vrai programme. En théorie comme en pratique, il n'y a aucune preuve.

Dans le test de stress, vous pouvez facilement dessiner de telles erreurs en utilisant ces deux fonctions. Vous en concluez vous-même que 48% de la charge du CPU a été mesurée en microsecondes ? Et ce n'est pas un test de stress ? Bien sûr qu'elle l'est.

Ce fil de discussion m'a incité à écrire une bibliothèque Benchmark afin de pouvoir simplement insérer un contrôle d'exécution dans la source. Et il en a largement profité, révélant et éliminant beaucoup de mauvaises choses.

Ainsi, un conseiller expert écrit de cette manière (plus précisément 20 conseillers experts en parallèle) charge un ordinateur domestique de 1,5%. Mais le VPS est à 50+%. Quand j'ai commencé à creuser, j'ai vu que la minuterie des microsecondes ralentissait. De même, si aucune alerte n'a été générée sur les machines domestiques, le VPS échoue.


Mais même cela n'était pas suffisant. Grâce à cette branche, un mécanisme d'instantanéité a été développé, dont la base est la suivante.

  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)); // Обязуем любой вызов снепшота в Тестере делать полноценным.
  }

C'est la base de tous les instantanés : si moins que le temps spécifié s'est écoulé depuis le dernier instantané, nous ne faisons rien. C'est cette approche qui vous permet d'économiser considérablement les ressources.

Bien entendu, le temps de rafraîchissement est court - par défaut, il est d'une milliseconde. C'est pourquoi on utilise un minuteur de microsecondes.


La lenteur de cette minuterie a provoqué l'effondrement du mécanisme d'instantané, car il fallait faire un instantané complet deux fois plus souvent que sur une machine complète.


Telles sont les tartes des freins de la minuterie de la microseconde. Mais quand je suis passé à un timer de millisecondes (au lieu de 16ms), tout a commencé à voler, même sur un VPS lent.

En ce qui concerne l'accélération du minuteur multimédia, il s'agit à nouveau de tests de stress sans tenir compte de la dégradation des performances globales. L'overclocking du taskmaster augmente l'overhead du système d'exploitation.

Qui se soucie de ces théories quand dans la pratique les gains sont colossaux. Peut-être, cela affecte-t-il certains jeux. Mais sur le VPS, c'était une paille de sauvetage.

 
fxsaber:

Donc c'est zéro microseconde pour moi aussi ! Seulement sur mon ordinateur personnel.

Ce fil de discussion m'a incité à écrire une bibliothèque Benchmark afin de pouvoir simplement insérer une vérification d'exécution dans la source. Et il en a largement profité, révélant et éliminant beaucoup de mauvaises choses.

Ainsi, un conseiller expert écrit de cette manière (plus précisément 20 conseillers experts en parallèle) charge un ordinateur domestique de 1,5%. Mais le VPS est à 50+%. Quand j'ai commencé à creuser, j'ai vu que la minuterie de la microseconde ralentissait. De même, si aucune alerte n'a été générée sur les machines domestiques, le VPS échoue.


Mais même cela n'était pas suffisant. Grâce à cette branche, un mécanisme d'instantanéité a été développé, dont la base est la suivante.

C'est la base de tous les instantanés : si moins que le temps spécifié s'est écoulé depuis le dernier instantané, nous ne faisons rien. C'est cette approche qui vous permet d'économiser considérablement les ressources.

Bien entendu, le temps de rafraîchissement est court - par défaut, il est d'une milliseconde. C'est pourquoi on utilise un minuteur de microsecondes.


Ainsi, à cause de la lenteur de ce timer, le mécanisme d'instantané s'est planté car l'instantané complet était pris beaucoup plus souvent que sur une machine complète.


C'est le genre de tarte des freins de la minuterie de la microseconde. Mais quand je suis passé à un timer de millisecondes (au lieu de 16ms), tout a commencé à voler, même sur un VPS lent.

Je ne me soucie pas de ces théories, tant que les avantages pratiques sont énormes. Peut-être que cela affecte certains jeux. Mais sur le VPS, c'était une paille de sauvetage.

Voyez comme c'est bien dit :

J'ai commencé à l'utiliser sur un VPS lent à la place de GetMicrosecondsCount. La charge a chuté de 50% à 2% sur le commerce réel.

La conclusion était inévitable : " tout ça à cause des microsecondes qui mesurent les freins, c'est ça l'accélération ".

Et soudain, il s'avère que "j'ai moi-même effectué des calculs d'un ordre de grandeur supérieur en raison d'une erreur logique". Et GetMicrosecondsCount était seulement un déclencheur pour cette erreur.

Le remaniement de GetTickCount est un correctif/crack pour cette erreur et le code du correctif n'a pas été montré. Parce que ce n'est pas simplement un remplacement de GetMicrosecondsCount -> GetTickCount ?

Pourquoi ça n'aurait pas pu être dit tout de suite ?


La logique suggère que l'accélération a été obtenue en amorçant explicitement la comptabilité (en passant des microsecondes aux millisecondes) et en réduisant la création d'instantanés par un multiple.
 
Je suis encore en train de réfléchir si je dois snapshoter SymbolInfoTick pour l'éviter.
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.

Ceci sur une machine qui broie 20 EAs avec 1,5% de CPU. Le LatencyMon montre que tout va bien.

Quelque chose dans l'architecture de MT5 donne ces décalages à tous les EAs en cours d'exécution en même temps. Et aucun pour moi.

 
Renat Fatkhullin:

La conversion en GetTickCount est un correctif/crack pour ce bug, et le code du correctif n'a pas été montré. Parce que ce n'est pas simplement un remplacement de GetMicrosecondsCount -> GetTickCount ?

Pourquoi ça n'aurait pas pu être dit tout de suite ?

Les discussions avec moi, cependant, se distinguent par la présence de ce qui est montré. Rien n'est caché, au contraire, tout est publié ouvertement.

Il y a certainement un test de stress. Il n'y avait pas d'autre moyen de le montrer visuellement.


Imaginez une fonction sous la forme d'une poupée matryoshka. Une mesure est prise de la matryoshka extérieure. En même temps, les poupées gigognes internes sont également mesurées. En conséquence, en raison du freinage à la microseconde, les poupées imbriquées externes affichent des chiffres sauvages sur leurs temps d'exécution, ce qui provoque une rafale d'alertes d'un type. Évidemment, 10 microsecondes pour un appel à GetMicrosecondsCount est terriblement coûteux. J'ai donc précipité les alertes.


La minuterie de milliseconde libre a commencé à donner soit 0µs, 1000µs ou 2000µs. Cela a permis de réduire considérablement le nombre d'alertes et de diminuer le freinage sur les appels de fonction de la minuterie.


À en juger par la logique, l'accélération a été obtenue en amorçant explicitement la comptabilité (en passant des microsecondes aux millisecondes) et en réduisant la création d'instantanés par un multiple.


Et avec les instantanés, c'est génial. Le chargement, comparé à celui de la machine maison (en microsecondes), n'est pas génial. Mais si vous le comparez avec ce qui était sur VPS, c'est comme le ciel et la terre.


SZZ, nous parlons maintenant de la faisabilité d'avoir dans MQL une minuterie de millisecondes, qui, malheureusement, n'existe pas. Vous ne pouvez pas faire de snapshot sur un VPS sans lui.

 
fxsaber:
J'envisage toujours le snapshot SymbolInfoTick pour éviter ce genre de choses.

Ceci sur une machine qui broie 20 EAs à 1,5% de CPU. Le LatencyMon montre que tout va bien.

Quelque chose dans l'architecture de MT5 donne ces décalages à tous les EAs en cours d'exécution en même temps. Et aucun pour moi.

Voici mon code et le temps de réponse stable : pas de centaines ou de milliers de microsecondes sur 20 graphiques en parallèle

   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


Combien de cœurs avez-vous et quel type de processeur ? i7-2600 ?

Un autre test de stress caché avec des millions de requêtes en parallèle ?


Soyez plus transparent. Ce n'est pas parce que vous avez posté un couple de simples appels _B que cela prouve vos autres affirmations. Vous oubliez brusquement le code et la description réelle des conditions dès que vous faites des affirmations farfelues.

Vous n'avez pas besoin d'imaginer quoi que ce soit dans votre esprit - dites et montrez ce que vous appelez et testez réellement. Pas un résultat déchiré du genre "j'ai exécuté un test de résistance inconnu et j'attends une alerte pour le montrer au monde entier", mais exactement le code complet du test.

Des questions se posent également sur la bibliothèque de mesures elle-même. Il y a beaucoup de choses inutiles, notamment des frais généraux.

 
fxsaber:

Nous parlons maintenant de l'utilité d'avoir un timer en millisecondes dans MQL, qui, malheureusement, n'existe pas. Vous ne pouvez pas faire de clichés sur l'UPU sans elle.

Il existe depuis longtemps un minuteur de millisecondes : EventSetMillisecondTimer()

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