Erreurs, bugs, questions - page 2878

 
fxsaber:

Cette fonction ne sera appelée qu'une seule fois pour l'ensemble du passage. Cela ne fait donc aucune différence.

donc oui... Mais je vais l'exécuter pendant quelques jours pour l'optimiser, je veux mesurer les performances d'une manière ou d'une autre ..... bien que je pense que la variante 1 sera plus efficace, il n'y aura pas 100500 fois de copie dans les tableaux.

 
Igor Makanu:

oui... Mais je vais faire tourner l'ordinateur pendant quelques jours pour l'optimiser, je veux mesurer les performances d'une manière ou d'une autre ..... même si je pense que l'option 1 sera plus efficace, il n'y aura pas 100500 fois de copie dans les tableaux.

La variante 2 est donc très probablement plus rapide, mais comme vous l'avez souligné plus haut, cela n'a pas d'importance.
 
TheXpert:
L'union n'est pas une copie de tableaux, c'est une interprétation différente du même espace mémoire. La deuxième option est donc probablement plus rapide, mais comme indiqué ci-dessus, cela n'a pas d'importance.
L'Union n'est pas aussi rapide qu'il n'y paraît. Malheureusement.
Je parie sur le premier.
 
Igor Makanu:

oui... Mais je vais faire tourner l'ordinateur pendant quelques jours pour l'optimiser, je veux mesurer les performances d'une manière ou d'une autre ..... même si je pense que l'option 1 sera plus efficace, il n'y aura pas 100500 fois de copie dans les tableaux.

il y a une vieille méthode pour mesurer la vitesse

dans le style de

for (int i=0 ; i< 1000000 ; i++) {notre code1}....
for (int i=0 ; i< 1000000 ; i++) {notre code2}....

 
Nikolai Semko:
L'Union n'est pas aussi rapide qu'il n'y paraît. Je parie sur le premier.

Je parie aussi sur le premier ! Les opérateurs binaires sont plusieurs fois plus rapides que l'opérateur if, même si le second n'en dispose pas.

 

vérifié :

#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count&&!_StopFlag;_i++){EX;} \
                                              printf("%s: loops=%llu ms=%llu",msg,count,GetMicrosecondCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   ulong sum = 0;
   SpeedTest(10, "tst 1 : ",
   {
      ushort in01A = (ushort)rand();
      ushort in01B = (ushort)rand();
      ushort in02A = (ushort)rand();
      ushort in02B = (ushort)rand();
      ushort in03A = (ushort)rand();
      ushort in03B = (ushort)rand();
      ushort in04A = (ushort)rand();
      ushort in04B = (ushort)rand();
      ushort in05A = (ushort)rand();
      ushort in05B = (ushort)rand();
      uint param[5];
      param[0] = (uint)in01A << (sizeof(ushort) * 8) | in01B;
      param[1] = (uint)in02A << (sizeof(ushort) * 8) | in02B;
      param[2] = (uint)in03A << (sizeof(ushort) * 8) | in03B;
      param[3] = (uint)in04A << (sizeof(ushort) * 8) | in04B;
      param[4] = (uint)in05A << (sizeof(ushort) * 8) | in05B;
      for(int i = 0; i < 5; i++) sum += param[i];
   });
//--   
   sum = 0;
   union ushortTouint
   {
      uint param[5];
      ushort in[10];
   }U;
   SpeedTest(10, "tst 2 : ",
   {
      ushort in00 = (ushort)rand();
      ushort in01 = (ushort)rand();
      ushort in02 = (ushort)rand();
      ushort in03 = (ushort)rand();
      ushort in04 = (ushort)rand();
      ushort in05 = (ushort)rand();
      ushort in06 = (ushort)rand();
      ushort in07 = (ushort)rand();
      ushort in08 = (ushort)rand();
      ushort in09 = (ushort)rand();
      ushortTouint u;
      u.in[0] = in00;
      u.in[1] = in01;
      u.in[2] = in02;
      u.in[3] = in03;
      u.in[4] = in04;
      u.in[5] = in05;
      u.in[6] = in06;
      u.in[7] = in07;
      u.in[8] = in08;
      u.in[9] = in09;
      for(int i = 0; i < 5; i++) sum += u.param[i];
   });

}

2020.10.15 21:48:01.401 SpeedTst (EURUSD,H1) tst 1 : : boucles=10000000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst 2 : : boucles=10000000000 ms=10862287

la différence n'est pas significative, il est très probable que si nous inversons les tests dans l'ordre inverse, les résultats seront inversés.

non critique

 
Igor Makanu:

pas une différence significative, il est très probable que si vous intervertissez les tests, les résultats seront inversés.

Il est fort probable que le compilateur ait généré le même code pour les deux cas. Dans ce cas, choisissez simplement celui que vous préférez subjectivement.

 
Igor Makanu:

vérifié :

2020.10.15 21:48:01.401 SpeedTst (EURUSD,H1) tst 1 : : boucles=10000000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst 2 : : boucles=10000000000 ms=10862287

la différence n'est pas significative, il est très probable que si nous inversons les tests dans l'ordre inverse, les résultats seront inversés.

non critique

Le script démontre ici que le temps de création des nombres aléatoires peut être non-uniforme et dépend du volume des variables créées))))

Et le code dont nous avons besoin dans ce nombre de répétitions me prend 0 ms.

Toujours pas de réponse.

ou l'optimiseur de code supprime quelque chose d'inutile
 
Alexandr Andreev:

Il semble exister un script qui démontre que le moment de la génération des nombres aléatoires peut être inégal.

non rand() est une fonction normale, elle fonctionne toujours de la même façon

Mais pour tester la vitesse, si vous l'initialisez avec des constantes, les tests seront "accélérés" pendant l'exécution - l'optimisation du code en MQL pendant l'exécution est une bonne chose.

en général, il a été vérifié plusieurs fois

Alexandr Andreev:

et beaucoup dépend de la taille des variables créées))))

Bien sûr, l'allocation de mémoire prend du temps, je l'ai vérifié, je teste à la fois des objets créés dynamiquement (nouveau pointeur) et des objets locaux, le test s'étend sur 100500 fois par nouveau et par suppression.

laquestion était que, dans le testeur, la mémoire est allouée aux variables une fois et non à chaque passage - mais j'ai besoin de tableaux d'uint, donc j'ai testé avec ce script, pas comme je l'ai écrit la première fois

Alexandr Andreev:

Et le code dont nous avons besoin pour ce nombre de répétitions me prend 0 ms.

toujours pas de réponse

Soit l'optimiseur de code coupe quelque chose d'inutile.

Avez-vous utilisé mon script ? - soit vous n'avez pas attendu jusqu'à la fin du test et vous avez interrompu ou vous avez débordé ulong - le premier paramètre de la macro est 10^ count



Andrei Trukhanovich:

il est très probable que le compilateur ait généré le même code pour les deux cas. dans ce cas, choisissez simplement celui que vous préférez subjectivement.

oui, peut-être

C'est ce que je demandais - j'ai lu à plusieurs reprises que les processeurs modernes peuvent exécuter plus d'une opération élémentaire par horloge en optimisant le pipeline d'instructions ..... beaucoup de bla-bla-bla... et le fait est que les instructions arithmétiques sont exécutées par le processeur dans un nombre imprévisible de cycles d'horloge.

Quant aux opérations de branchement et d'allocation de mémoire, elles sont très mal optimisées par le processeur, donc ne cherchez pas l'optimisation dans la simplification de l'arithmétique, essayez d'écrire un code maximalement linéaire avec un minimum de branchement, et il vaut mieux déclarer les variables et leur attribuer des valeurs juste avant les calculs, ce qui permet au pipeline d'instructions et à la prédiction de l'échantillonnage du cache d'optimiser ce code.


En d'autres termes, l'échantillonnage des valeurs des éléments du tableau (adressage) ne sera probablement pas crucial pour la vitesse - je pensais qu'il y aurait un avantage de décalage par rapport à l'union, mais il s'avère qu'il n'y a pas de différence du tout.

 
Igor Makanu:

Je l'ai retravaillé un peu

(il est préférable de ne pas utiliser une macro de cette façon ;)

#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count;_i++){EX;} \
                                              printf("%s: loops=%llu ms=%llu",msg,count,GetMicrosecondCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
{
   ulong sum = 0;
   uint in01A = (uint)rand();
   uint in01B = (uint)rand();
   uint in02A = (uint)rand();
   uint in02B = (uint)rand();
   uint in03A = (uint)rand();
   uint in03B = (uint)rand();
   uint in04A = (uint)rand();
   uint in04B = (uint)rand();
   uint in05A = (uint)rand();
   uint in05B = (uint)rand();
   uint param[5];
   SpeedTest(22, "tst 1 : ",
   {
      sum += in01A << (sizeof(ushort) * 8) | in01B;
      sum += in02A << (sizeof(ushort) * 8) | in02B;
      sum += in03A << (sizeof(ushort) * 8) | in03B;
      sum += in04A << (sizeof(ushort) * 8) | in04B;
      sum += in05A << (sizeof(ushort) * 8) | in05B;
   //   for(int i = 0; i < 5; i++) sum += param[i];
   });
   Print(sum);
   }
//--  

   ulong sum = 0;
   ushort in00 = (ushort)rand();
   ushort in01 = (ushort)rand();
   ushort in02 = (ushort)rand();
   ushort in03 = (ushort)rand();
   ushort in04 = (ushort)rand();
   ushort in05 = (ushort)rand();
   ushort in06 = (ushort)rand();
   ushort in07 = (ushort)rand();
   ushort in08 = (ushort)rand();
   ushort in09 = (ushort)rand(); 
   sum = 0;
   union ushortTouint
   {
      uint param[5];
      ushort in[10];
   }U;
      ushortTouint u;
   SpeedTest(22, "tst 2 : ",
   { 
      u.in[0] = in00;
      u.in[1] = in01;
      sum +=u.param[0];
      u.in[2] = in02;
      u.in[3] = in03;
      sum +=u.param[1];
      u.in[4] = in04;
      u.in[5] = in05;
      sum +=u.param[2];
      u.in[6] = in06;
      u.in[7] = in07;
      sum +=u.param[3];
      u.in[8] = in08;
      u.in[9] = in09;
      sum +=u.param[4];
    //  Comment(121);
   //  for(int i = 0; i < 5; i++) sum += u.param[i];
   });
Print(sum);
}
Raison: