Erreurs, bugs, questions - page 2778

 

Les programmes MQL5 travaillent (méthodes Get/Set) avec un graphique via une file d'attente de transactions.

Cela permet de libérer l'interface graphique et le terminal lui-même des blocages inévitables qui seraient un problème pour les programmes MQL5.

L'asynchronie transactionnelle permet une écriture ou une lecture rapide dans les modes séparés et active immédiatement le mode de synchronisation en mélangeant les méthodes Set et Get.

En d'autres termes, il est préférable d'effectuer un Set 1000 fois asynchrone, puis un Get 1000 fois, plutôt que d'effectuer alternativement un Get & Set, transformant ainsi la file d'attente en un processus synchrone. Parce que vous devez vous assurer que le Set asynchrone précédent était exactement superposé et que vous pouvez maintenant le lire.


Vous devez utiliser les fonctions du système avec précaution et les mettre en cache chaque fois que possible.

 
Renat Fatkhullin:

Vous devez utiliser les fonctions système avec précaution et les mettre en cache lorsque cela est possible.

Bonjour, le problème est un peu différent - le ChartGetInteger et les fonctions similaires sont TRÈS lents à s'exécuter.
Lors du passage de la version 2009 à la version 2485, le temps d'exécution de ChartGetInteger est passé de 5 ms à 200-250 ms. Ce problème est particulièrement visible avec plus de 50 graphiques ouverts.
Système : Terminal Windows 10 build 18363, Intel Core i7-7700HQ @ 2.80GHz, 19 / 31 GB de mémoire, 262 / 640 GB de disque, moniteur 4K, NVidia 1050Ti
Lecode de la description du problème a été utilisé: https://www.mql5.com/en/forum/342152.

Causes possibles du problème :

Bugs, bugs, problèmes

Sergey Dzyublik, 2020.06.13 19:20

J'ai comparé l'implémentation de la fonction ChartGetInteger pour deux versions de MT5 2009 et MT5 2485, le problème est peut-être le suivant :
1. En 2485, pour lire les champs "atomiques" d'un objet graphique, nous utilisons des opérations plutôt lentes :
mfence; lock mov eax,[rax+2C] ;
Alors que dans la version 2009, cela est fait en utilisant : lock xadd [rcx+2C],eax

Il semble également que la logique et le temps d'attente possible dans ntdll_RtlEnterCriticalSection aient considérablement changé.
Auparavant, en 2009, une section critique ne vérifiait qu'une paire de valeurs reçues, sans aucune opération atomique.
Et en 2485, les objets de la liste chaînée du tableau peuvent également être énumérés.


Vraisemblablement, le problème a pu se produire lorsque le crash a été corrigé lors du travail avec les fonctions graphiques dans le cadre de la migration vers le nouveau compilateur (il y a environ 2-3 mois).
Le code assembleur pour l'appel ChartGetInteger dans MT5 (build 2485) est joint.



 
Allons voir ça.
 
Renat Fatkhullin:
Regardez ça.

Étapes de la lecture :

long chart_id;

int OnInit(){
   for(int i = 0; i < 95; ++i){
      ChartOpen(_Symbol, _Period);
   }

   chart_id = ChartID();
   EventSetMillisecondTimer(250);
   return(INIT_SUCCEEDED);
}

void OnTimer(){
  ulong t=GetMicrosecondCount();
  long autoscroll = ChartGetInteger(chart_id, CHART_AUTOSCROLL);
  ulong delay =(GetMicrosecondCount()-t)/1000;
  if (delay>0){
    Print("Execution delay: ",delay, " ms");
  }
}


1. Prenez un terminal MT propre, ouvrez un graphique sur celui-ci, exécutez l'EA compilé ci-dessus sur ce graphique.
2. Après avoir ouvert les 95 nouveaux graphiques, élargissez la fenêtre graphique à la largeur totale de l'espace graphique dans MT, si cela n'a pas été fait auparavant.
3. Pour passer d'un onglet de graphique à un autre et enregistrer dans le journal les valeurs d'exécution de ChartGetInteger.
Pour fermer tous les graphiques ouverts, vous pouvez appuyer sur CTRL+W et le maintenir enfoncé.


Résultat de MT5 (build 2009) :

2020.06.14 15:33:43.173 Test123456 (EURUSD,H1)  Execution delay: 2 ms
2020.06.14 15:33:43.674 Test123456 (EURUSD,H1)  Execution delay: 3 ms
2020.06.14 15:33:44.177 Test123456 (EURUSD,H1)  Execution delay: 5 ms
2020.06.14 15:33:44.422 Test123456 (EURUSD,H1)  Execution delay: 4 ms
2020.06.14 15:33:44.673 Test123456 (EURUSD,H1)  Execution delay: 2 ms
2020.06.14 15:33:44.923 Test123456 (EURUSD,H1)  Execution delay: 3 ms
2020.06.14 15:33:45.173 Test123456 (EURUSD,H1)  Execution delay: 2 ms
2020.06.14 15:33:45.423 Test123456 (EURUSD,H1)  Execution delay: 2 ms
2020.06.14 15:33:45.672 Test123456 (EURUSD,H1)  Execution delay: 2 ms


Résultat MT5 (buidl 2485) :

2020.06.14 15:33:12.947 Test123456 (EURUSD,H1)  Execution delay: 163 ms
2020.06.14 15:33:13.198 Test123456 (EURUSD,H1)  Execution delay: 1 ms
2020.06.14 15:33:13.293 Test123456 (EURUSD,H1)  Execution delay: 1 ms
2020.06.14 15:33:13.831 Test123456 (EURUSD,H1)  Execution delay: 287 ms
2020.06.14 15:33:14.702 Test123456 (EURUSD,H1)  Execution delay: 136 ms
2020.06.14 15:33:15.316 Test123456 (EURUSD,H1)  Execution delay: 3 ms
2020.06.14 15:33:15.677 Test123456 (EURUSD,H1)  Execution delay: 110 ms
2020.06.14 15:33:17.041 Test123456 (EURUSD,H1)  Execution delay: 221 ms


Comparaison des résultats et des conclusions :
1. Le nombre d'enregistrements qui sont affichés dans la version 2009 est beaucoup plus élevé que dans la version 2485.
Lafonction ChartGetInteger dans des "conditions normales" est devenue plus rapide après le passage à la version 2485.

2. Le temps d'exécution maximal pour la version 2009 - 15 ms, et pour la version 2485 - 310 ms.
La fonction ChartGetInteger dans des "conditions défavorables" devient jusqu'à 20 fois plus lente après le passage à la version 2485.

3. de la même manière que vous pouvez estimer à l'œil la vitesse d'ouverture de 95 cartes.
Pour les deux builds, on remarque la complexité "exponentielle" du nombre de graphiques ouverts précédemment, ainsi qu'une exécution nettement plus rapide dans la build 2009.

 
Stanislav Korotky :

D'après les journaux, la décélération de l'un n'a pas coïncidé avec la décélération de l'autre, c'est-à-dire qu'elle n'a pas été simultanée. Le problème se situe donc dans le terminal lui-même.

Le journal n'est imprimé que toutes les minutes (la traduction a gâché l'horodatage ! !), je pourrais vérifier plus précisément, mais ça n'en vaut pas la peine.

Je l'ai essayé sur plusieurs terminaux et il montre clairement que les pics ne sont PAS simultanés. Il s'agit clairement d'un problème lié à MT5.

 
Renat Fatkhullin :

Les programmes MQL5 travaillent (méthodes Get/Set) avec un graphique via une file d'attente de transactions.

Cela permet de libérer l'interface graphique et le terminal lui-même des blocages inévitables qui seraient un problème pour les programmes MQL5.

L'asynchronie transactionnelle permet une écriture ou une lecture rapide dans les modes séparés et active immédiatement le mode de synchronisation en mélangeant les méthodes Set et Get.

En d'autres termes, il est préférable d'effectuer un Set 1000 fois asynchrone, puis un Get 1000 fois, plutôt que d'effectuer alternativement un Get & Set, transformant ainsi la file d'attente en un processus synchrone. Parce que vous devez vous assurer que le Set asynchrone précédent était exactement superposé et que vous pouvez maintenant le lire.


Vous devez utiliser les fonctions du système avec précaution et les mettre en cache chaque fois que possible.

C'est un système compréhensible et bon. Mais je pense qu'il y a un problème quelque part, comme @Sergey Dzyubli l'a également démontré.
Sergey Dzyublik
Sergey Dzyublik
  • www.mql5.com
Добавил тему Вход через MQL5.community (OAuth) В настройках профиля появилась новая вкладка Приложения (https://www.mql5.com/ru/users/USER_NAME/apps): Эта функция позволяет людям авторизоваться на вашем сайте или в приложении, используя аккаунт MQL5.community. Технология проста и безопасна. Она Добавил...
 
Alexey Navoykov:
Pour autant que je sache, l'appel à ChartRedraw ne provoque pas le redécoupage immédiat du graphique. Le redécoupage ne se produit que lorsqu'une méthode Get est appelée.
Et ChartRedraw est essentiellement la même méthode asynchrone. Votre mesure de BuildChart n'est donc pas fiable.

essayez d'intervertir ces deux lignes

alors il n'y aura rien d'asynchrone dans la mesure et voyez ce qui se passe. Ce sera encore plus rapide.

 
fxsaber:
Je suis resté muet pendant longtemps, ne comprenant pas ce que le compilateur n'aime pas dans cette ligne.

J'ai oublié d'écrire si. J'ai pensé que ce serait une bonne idée de mâcher le message pour de tels abrutis.

Il m'a demandé de faire une description et un exemple pour toutes les erreurs et avertissements du compilateur il y a environ 5 ans, peut-être plus.

Vous pouvez peut-être faire mieux.

 
Renat Fatkhullin:

Les programmes MQL5 travaillent (méthodes Get/Set) avec un graphique via une file d'attente de transactions.

Cela permet de libérer l'interface graphique et le terminal lui-même des blocages inévitables qui seraient un problème pour les programmes MQL5.

L'asynchronie transactionnelle permet une écriture ou une lecture rapide dans les modes séparés et active immédiatement le mode de synchronisation en mélangeant les méthodes Set et Get.

En d'autres termes, il est préférable d'effectuer un Set 1000 fois asynchrone, puis un Get 1000 fois, plutôt que d'effectuer alternativement un Get & Set, transformant ainsi la file d'attente en un processus synchrone. Parce que vous devez vous assurer que le Set asynchrone précédent était exactement superposé et que vous pouvez maintenant le lire.


Vous devez utiliser les fonctions du système avec précaution et les mettre en cache chaque fois que possible.

J'ai bien compris que non seulement les méthodes Set sont asynchrones, mais aussi Get ?
Ilyas s'est trompé ici , n'est-ce pas ?
Et Slava avait raison quand il disait que la méthode ChartXYToTimePrice est asynchrone ? Après tout, la méthode ChartXYToTimePrice fait très probablement référence aux méthodes Get.

La documentation ne parle que de l'asynchronisme des méthodes Set.

 
Nikolai Semko:

Ai-je bien compris que non seulement les méthodes Set sont asynchrones, mais aussi Get ?

On vous a déjà répondu à cette question, mais d'après vos propos, vous n'avez pas besoin de "récits académiques"...
Tu vas te décider là-bas ou quoi ?

Raison: