La toile est cool ! - page 19

 
Renat Fatkhullin:

Il s'avère que je regardais la fréquence de génération du web, et non la fréquence de sortie.

Ce sont des nombres différents, des multiples les uns des autres.

Il s'avère que j'ai calculé la fréquence de génération du web (sans sortie) et la fréquence de sortie (sans génération) de manière un peu erronée.

Voici une version plus correcte.


Résultats sur mon processeur :

Si vous prenez le temps purement en générant une image de 200 cercles lissés sans sortie, cela se produit à environ 500 images par seconde.

former une image de 200 cercles non lissés sans sortie - environ 1000 fps.

La fréquence de la sortie de l'image (canevas) elle-même (fonction Update) est d'environ 650 images par seconde.

Vous avez vraiment travaillé dur !

Dossiers :
 
Renat Fatkhullin:

Attention aux conversions massives de types (int)double ou (double)int et au mélange int+double dans les opérations mat en général.

Cela donne la surcharge la plus folle au processeur - juste une commande assembleur aussi coûteuse. Si vous comptez en double, continuez à compter en double et ne passez pas aux types entiers.

Les commandes comme cvtsi2sd/cvttsd2si sont très longues. Un petit conseil dans l'article"L'instruction x86 la plus lente", méchant numéro 2.

Merci pour cet article très utile.


Mais pour être honnête, je ne comprends pas pourquoi alors dans ce simple script :

#define  Num 1000000 
void OnStart()
  {
    double arr[Num];
    for (int i=0;i<Num;i++) arr[i]=(double) rand()/(1+rand()%100); // инициализируем массив случайными числами double от 0.0 до 32767.0
    
    long sumL=0;
    
    ulong t1=GetMicrosecondCount();
    for (int i=0;i<Num;i++) sumL+=(long)arr[i]; // сумма long
    t1=GetMicrosecondCount()-t1;
    
    double sumD=0;
    
    ulong t2=GetMicrosecondCount();
    for (int i=0;i<Num;i++) sumD+=arr[i];      // сумма double
    t2=GetMicrosecondCount()-t2;  
    
    Print ("Сумма long   = "+ string(sumL)+ ", время суммирования "+string(t1)+" микросекунд");
    Print ("Сумма double = "+ DoubleToString(sumD)+ ", время суммирования "+string(t2)+" микросекунд");   
  }

la somme de long avec conversion du type double en long est beaucoup plus rapide que la somme de double du même tableau sans conversion

2019.01.15 22:21:46.410 TestSpeedDoubleAndInt (NZDUSD,M5)       Сумма long   = 849290923,          время суммирования 748  микросекунд
2019.01.15 22:21:46.410 TestSpeedDoubleAndInt (NZDUSD,M5)       Сумма double = 849764484.23059070, время суммирования 1393 микросекунд
 

Tout d'abord, il faut regarder le code assembleur et le résultat des optimisations de cas extrêmement simples (la supermicrosynthèse est depuis longtemps trompeuse). Il est facile de se heurter à un cas idéal de mise en œuvre d'un convoyeur.

Deuxièmement, presque personne ne peut garantir comment tel ou tel code sera compilé et combien de temps il prendra pour s'exécuter.

Il suffit d'ajouter une ligne/commande supplémentaire dans le code pour que la vitesse change radicalement. Le vrai code/données pourrait bien sortir du cache L1/L2 et c'est tout.

Comment cela a-t-il fonctionné pour vous ? En théorie/super-synthetique, il semble que les commandes entières aident à la vitesse, mais dans le code réel, c'est un gouffre. Parce qu'il y a des dizaines ou des centaines de fois plus de code, pas de convectorisation, des sauts constants des calculs entiers aux calculs réels et l'optimisation est limitée.

 
Renat Fatkhullin:


Pourquoi l'initialisation des tableaux de tous types est-elle plus de 10 fois plus lente dans MQL4 que dans MQL5 ?

 
Реter Konow:

Pourquoi l'initialisation des tableaux de tous types est-elle plus de 10 fois plus lente dans MQL4 que dans MQL5 ?

Parce que tous les tableaux y sont dynamiques et que le langage est dix fois plus lent.

 
C'est une réponse cool)).
Dix fois plus lent parce que dix fois plus lent)).
 

Un indicateur ultra-rapide de centaines de moyennes mobiles, implémenté sur Canvas.

100 lignes MA (pas de période 10) - temps de calcul et d'affichage à l'écran - 4-7 millisecondes


1000 lignes MA (période étape 1) - temps de calcul et d'affichage - 20-30 millisecondes.


Je n'ai pas trop testé le code. Il peut y avoir des bugs. Implémenté seulement pour une barre d'un pixel d'épaisseur (elle est forcée à cette échelle). Le taux de rafraîchissement de l'écran n'est pas non plus optimisé. Toutes les lignes sont calculées et entièrement sorties à chaque tick.

#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164
#property indicator_chart_window

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input int MA=1000;   // максимальный период скользящих средних
input int stepMa=10; // шаг скользящих средних

double  Close[];
long Total;
int Ma;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   ChartSetInteger(0,CHART_SCALE,0,0);
   ChartSetInteger(0,CHART_FOREGROUND,true);
   CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
   Total=SeriesInfoInteger(_Symbol,_Period,SERIES_BARS_COUNT);
   if (Total<(MA+W.BarsInWind)) Ma=(int)Total-1-W.BarsInWind; else Ma=MA;
   if (Ma<=0) Ma=1;
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[])
  {
   CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
   Print("Время формирования кадра = "+(string)(nMA()/1000)+" миллискунд");
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      ChartSetInteger(0,CHART_SCALE,0,0);
      CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
      Print("Время формирования кадра = "+(string)(nMA()/1000)+" миллискунд");
     }
  }
//+------------------------------------------------------------------+

ulong nMA()
  {
   ulong t=GetMicrosecondCount();
   int preY=0;
   Canvas.Erase();
   double S=0;
   for(int i=0;i<Ma; i++) S+=Close[i];

   for(int Per=Ma;Per>0;)
     {
      double s=S;
      uint Clr=Grad((double)Per/Ma);
      for(int x=0; x<W.BarsInWind;x++)
        {
         int Y=(int)(Canvas.Y(s/Per)-0.5);
         if(x>0) if(fabs(Y-preY)>1) Canvas.Line(x-1,preY,x,Y,Clr);
         else Canvas.PixelSet(x,Y,Clr);
         if((Ma+x)<ArraySize(Close)) s=s-Close[x+Ma-Per]+Close[Ma+x]; else break;
         preY=Y;
        }
      for(int j=0; j<stepMa; j++) if(Per>0){ S=S-Close[Ma-Per]; Per--;} else break;
     }
   Canvas.Update();
   return GetMicrosecondCount()-t;
  }
//+------------------------------------------------------------------+
uint Grad(double p)
  {
   static uint Col[6]={0xFF0000FF,0xFFFF00FF,0xFFFF0000,0xFFFFFF00,0xFF00FF00,0xFF00FFFF};
   if(p>0.9999) return Col[5];
   if(p<0.0001) return Col[0];
   p=p*5;
   int n=(int)p;
   double k=p-n;
   argb c1,c2;
   c1.clr=Col[n];
   c2.clr=Col[n+1];
   return ARGB(255,c1.c[2]+uchar(k*(c2.c[2]-c1.c[2])+0.5),
                   c1.c[1]+uchar(k*(c2.c[1]-c1.c[1])+0.5),
                   c1.c[0]+uchar(k*(c2.c[0]-c1.c[0])+0.5));
  }
//+------------------------------------------------------------------+
Dossiers :
MultiMA.mq5  9 kb
 
Nikolai Semko:

Un indicateur ultra-rapide de centaines de moyennes mobiles, implémenté sur Canvas.

100 lignes MA (pas de période 10) - temps de calcul et d'affichage à l'écran - 4-7 millisecondes


1000 lignes MA (étape 1 de la période) - temps de calcul et d'affichage - 20-30 millisecondes


cool, avec des indicateurs standards tout serait mort

 
Maxim Dmitrievsky:

cool, les indicateurs standards auraient accroché tout ça.

et ensuite il y aurait un kilomètre de code...

peut-être même que cela ne peut être fait qu'avec un modèle. Je ne connais pas la limitation du nombre de lignes d'indicateur dans le corps d'un indicateur.

 
Nikolai Semko:

...

Pas au courant de la limitation du nombre de lignes d'indicateur dans le corps d'un indicateur.

Il y a une limite. Il est possible de créer jusqu'à 512 tampons indicateurs >>>https://www.mql5.com/ru/docs/indicators

Документация по MQL5: Технические индикаторы
Документация по MQL5: Технические индикаторы
  • www.mql5.com
Все функции типа iMA, iAC, iMACD, iIchimoku и т.п., создают в глобальном кеше клиентского терминала копию соответствующего технического индикатора. Если копия индикатора с этими параметрами уже существует, то новая копия не создается, а увеличивается счетчик ссылок на данную копию. Эти функции возвращают хэндл соответствующей копии индикатора...