Erreurs, bugs, questions - page 2161

 
Nikolai Semko:

J'ai essayé un tableau statique - même chose.

Aussi rapide que soit sqrt, j'ai du mal à croire que cette fonction puisse être 10 fois plus rapide que la simple lecture d'un élément de tableau.

À ce stade, un grand nombre des anciennes techniques d'optimisation ne fonctionnent plus.


De plus, si dans mon exemple, je veux réduire la taille de la toile, disons 50x50 (pour cela, il y a un paramètre d'entrée Size, vous devez définir 50 au lieu de 0),

et le tableau sera beaucoup plus petit (5000 éléments), l'image de la vitesse change de manière significative. Il n'y a plus de contraste aussi fort.

Mais ce que je ne comprends pas, c'est que la taille du tableau affecte la vitesse d'accès à ses éléments.

Il n'y a pas de preuve propre de vos calculs, vous faites des hypothèses basées sur un code très altéré.

Vous négligez une tonne de calculs auxiliaires qui se trouvent dans votre code et qui ont un impact important sur les résultats.

 
Renat Fatkhullin:


Il n'y a pas de preuve claire de vos calculs, vous faites des hypothèses basées sur un code très confus.

Vous négligez une tonne de calculs auxiliaires qui se trouvent dans votre code et qui ont un impact important sur les résultats.

Tout ce que je peux constater, c'est qu'en remplaçant sqrt par une simple lecture d'un tableau, la vitesse de calcul globale diminue d'un facteur 4. Et la proportion globale de sqrt dans ce calcul assez important de chaque pixel n'est guère supérieure à 10%, voire à quelques %.

Une anomalie évidente !

J'ai même fait l'erreur de dire que le temps d'accès à un élément d'un tableau est 10 fois le temps du sqrt. Beaucoup plus étant donné que sqrt est si rapide et que le ralentissement global est si grand.

 
Nikolai Semko:

Je constate simplement qu'en remplaçant sqrt par une simple lecture d'un tableau, la vitesse de calcul globale diminue d'un facteur 4. Et la proportion globale de sqrt dans ce calcul assez important de chaque pixel n'est guère supérieure à 10%, voire à quelques %.

Une anomalie évidente !

J'ai expliqué pourquoi. Les optimisations des mathématiques des années 90 ne fonctionnent plus.

Mais vous continuez à faire les affirmations suivantes, basées sur du code réel altéré. Sur le plan végétal, ils ont tort.

À ce niveau de [non]pureté technique, je ne discuterai pas de ces questions.

 
Renat Fatkhullin:

J'ai expliqué pourquoi. Les optimisations des mathématiques des années 90 ne fonctionnent plus.

Mais vous continuez à faire les affirmations suivantes sur la base d'un code vraiment désordonné. Plausiblement défectueux.

À ce niveau de [non]pureté technique, je ne discuterai pas de ces questions.

Je ne comprends pas de quelle optimisation mathématique vous parlez. Et je ne faisais aucune affirmation, je me demandais juste quelle était la source des freins.

Où sont le désordre et l'optimisation dans ce code original ?

#include <Canvas\Canvas.mqh>

void OnStart()
  {
   ChartSetInteger(0,CHART_FOREGROUND,true);
   CCanvas C;
   int Width=(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);                               // получаем Ширину окна
   int Height=(ushort)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);                             // получаем Высоту окна
   if(!C.CreateBitmapLabel(0,0,"CanvasExamlple",0,0,Width,Height,COLOR_FORMAT_XRGB_NOALPHA)) // создаем канвас размером текущего окна
   Print("Error creating canvas: ",GetLastError()); 
   uint i=0,j=100000;
   int size=Width*Height;
   uchar h[25600];
   for (int w=0;w<25600;w++) 
   h[w]= uchar(128+128*sin(double(w)/256));//создаем массив для ускорения работы
   double X1=0,Y1=0,X2=0,Y2=0,X3=0,Y3=0,X4=0,Y4=0;
   while(!IsStopped())
     {
      int pos=int(i%size);
      if(pos==0)
        {
         C.Update();
         //Sleep(30);
         X1= Width/2-(sin((double)j/100)*(double)Width/2);
         Y1= Height/2-(cos((double)j/140)*(double)Height/2);
         X2= Width/2+(cos((double)j/80)*(double)Width/2);
         Y2= Height/2+(sin((double)j/20)*(double)Height/2);
         X3= Width/2+(cos((double)j/85)*(double)Width/2);
         Y3= Height/2+(sin((double)j/65)*(double)Height/2);
         X4= Width/2+(cos((double)j/152)*(double)Width/2);
         Y4= Height/2+(sin((double)j/42)*(double)Height/2);
         j++;
        }
      int X=pos%Width;
      int Y=int(pos/Width);
      double D1=sqrt((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y));
      double D2=sqrt((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y));
      double D3=sqrt((X3-X)*(X3-X)+(Y3-Y)*(Y3-Y));
      double D4=sqrt((X4-X)*(X4-X)+(Y4-Y)*(Y4-Y));
      double d= (D1+D2)/(D1+D2+D3+D4);
      C.PixelSet(X,Y,XRGB(h[int(d*11520)],h[int(d*17920)],h[int(d*6400)]));
      i++;
     }
   C.Destroy();
  }

Vous pouvez utiliser ce code plus générique, mais grâce à l'utilisation de boucles et de tableaux, la vitesse de cadrage des images est presque réduite de moitié :

#include <Canvas\Canvas.mqh>
#property script_show_inputs 
input int N=8; // количество центов гравитации

void OnStart()
  {
   ChartSetInteger(0,CHART_FOREGROUND,true);
   CCanvas C;
   int Width=(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);                               // get Window width
   int Height=(ushort)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);                             // get Window height 
   if(!C.CreateBitmapLabel(0,0,"CanvasExamlple",0,0,Width,Height,COLOR_FORMAT_XRGB_NOALPHA)) // create canvas with the size of the current window
      Print("Error creating canvas: ",GetLastError());
   uint i=0,j=100000;
   int size=Width*Height;
   uchar h[];
   ArrayResize(h,25600);
   for(int w=0;w<25600;w++) h[w]=uchar(128+128*sin(double(w)/256)); //create an array to speed up the work
                                                                  
   int k[]; ArrayResize(k,N*2);
   for(int w=0;w<N*2;w++) k[w]=20+rand()%200;
   double XP[],YP[],D[],D1[];
   ArrayResize(XP,N);
   ArrayResize(YP,N);
   ArrayResize(D,N);
   ArrayInitialize(XP,0);
   ArrayInitialize(YP,0);
  
   while(!IsStopped())
     {
      int pos=int(i%size);
      if(pos==0)
        {
         C.Update();
         for(int w=0;w<N;w++)
           {
            XP[w]= Width/2-(sin((double)j/k[2*w])*(double)Width/2);
            YP[w]= Height/2-(cos((double)j/k[2*w+1])*(double)Height/2);
           }
         j++;
        }
      int X=pos%Width;
      int Y=int(pos/Width);

      for(int w=0;w<N;w++) D[w]= sqrt((XP[w]-X)*(XP[w]-X)+(YP[w]-Y)*(YP[w]-Y));
      double S1=0,S2=0;
      for(int w=0;w<N/2;w++) S1+=D[w];
      for(int w=0;w<N;w++) S2+=D[w];
      double d=S1/S2;
      
      C.PixelSet(X,Y,XRGB(h[int(d*11520)],h[int(d*17920)],h[int(d*6400)]));
      i++;
     }
   C.Destroy();
  }
//+------------------------------------------------------------------+
 

Optimisation des mathématiques : essayer d'utiliser des tableaux au lieu de sqrt.

Vous ne voyez pas le désordre et c'est là l'origine de votre incompréhension des règles des tests de performance. Si vous testez le tableau précalculé par rapport au calcul, vous devez supprimer tout ce qui est superflu. Absolument tout ce qui est inutile.

Vous avez fait beaucoup d'affirmations. Vous devez être capable de lire les textes du côté du destinataire et de les nettoyer des défenses non fonctionnelles de l'auteur.

 
Renat Fatkhullin:

Optimisation des mathématiques : essayer d'utiliser des tableaux au lieu de sqrt.

Oh, au diable le sqrt. Je me suis déjà rendu compte que dans le cas de cette fonction particulière, cela n'a pas de sens. Qu'y a-t-il de mal à essayer ? Mais maintenant je le sais.

Au fait, l'utilisation du tableau h[] dans cet exemple permet également un gain de vitesse considérable par rapport à l'utilisation de sin().

La question porte sur autre chose :

Pourquoi l'utilisation de l'accès aux cellules d'un grand tableau augmente-t-elle le temps de calcul de plusieurs fois alors qu'on ne s'attendait qu'à quelques pour cent ?

Vous ne voyez pas la litière et c'est là l'origine de votre incompréhension des règles des tests de performance.Si vous testez le tableau précalculé par rapport au calcul, vous devez supprimer tout ce qui est superflu. Absolument tout ce qui est inutile.

Vous savez, Renat, ce n'est pas une honte de recevoir une gifle de vous, mais même un honneur.

D'après ce que je comprends, les déchets sont des choses inutiles qui peuvent et doivent être éliminées. Mais dans ce cas, il n'y a rien à nettoyer, sinon le code cessera de fonctionner.

Je ne teste pas"tableau précalculé contre calcul" mais j'analyse la vitesse de formation des images.

Dans mon cas, je n'ai pas besoin de tests, car j'ai un ordinateur portable faible et je peux voir la différence entre 25 fps et 6 fps sans aucun test.

Les affirmations que vous avez faites sont massives. Vous devez être capable de lire les textes du côté du destinataire et de les débarrasser des défenses inapplicables de l'auteur.

Je n'ai fait que quelques hypothèses, pas des affirmations :

- "Il est logique de supposer que la lecture du tableau SQRT[x] est plus rapide que la fonction sqrt(x)".

-"On pourrait supposer que le compilateur accède à un grand tableau d'une manière étrange, et à chaque tour de boucle, il semble "oublier" le tableau et faire une sorte d'indexation de service à chaque fois. "

Mais je me risque quand même à faire cette déclaration parce que, bien que je sois un programmeur autodidacte, mais autodidacte avec une grande expérience et qui comprend quelque chose aux processus à l'intérieur du processeur, parce qu'il fut un temps où mon programme préféré était Numega SoftIce, grâce auquel je fouillais dans des tonnes de code extraterrestre au niveau assembleur.

- Je vous assure qu'il y a un bug algorithmique dans votre compilateur, concernant l'accès aux tableaux, (peut-être qu'il n'apparaît qu'avec des tableaux suffisamment grands), que votre équipe trouvera facilement, si vous mettez vecteur d'effort dans cette direction. Et mon exemple vous aidera.

Je pourrais même argumenter. ))

 

Lorsque vous parcourez un tableau en boucle, à chaque nouvel accès, il est probable qu'il se trouve dans le cache du processeur. C'est pourquoi il fonctionne plus rapidement.

S'il y a un code entre les accès, il est probable qu'il y ait un manque de cache. Cela explique également la différence de manipulation d'une grande et d'une petite table.

En outre, il existe d'autres cas non évidents. Il est donc nécessaire de tester la version finale non simplifiée du code.

 
Les gars, comment pouvez-vous dire dans les modèles de fonction qu'une fonction avec le type enum a été appelée?
 
Vladimir Pastushak:
Les gars, dites-moi comment déterminer, dans les modèles de fonctions, que la fonction de type enum est appelée?
enum est une énumération d'entiers.
0,1,2,3 ..., etc...
 
Artyom Trishkin:
Enum est une énumération de nombres entiers.
0,1,2,3..., etc...

Si un modèle de fonction contient

EnumToString() ;

des problèmes surviennent...