Hatalar, hatalar, sorular - sayfa 2161

 
Renat Fatkhullin :


Kodu dikkatlice kontrol edelim. Gerçek sebebin ne olduğunu bulmak ilginç.

Güzel! Teşekkür ederim! ben de ilgileniyorum

Ve sqrt gerçekten çok hızlı. Bir nanosaniyeden daha az :)). Fantezi!

 
Nikolai Semko :

Statik bir dizi denedim - aynı şey.

sqrt kadar hızlı, bu işlevin bir dizi öğesini okumaktan 10 kat daha hızlı olabileceğine inanmakta zorlanıyorum.

Şu anda birçok eski optimizasyon tekniği artık çalışmıyor.


Ayrıca, örneğimde tuvalin boyutu küçültülmüşse, diyelim ki 50x50 (bunun için Size bir giriş parametresi var, 0 yerine 50 ayarlamanız gerekiyor),

ve dizi çok daha küçük (5000 eleman) olacak, ardından hız resmi belirgin şekilde değişecektir. Artık böyle güçlü bir kontrast yok.

Ama benim için net değil , öğelerine erişim hızı dizinin boyutuna mı bağlı ?

Hesaplamalarınızın saf bir kanıtı yok, çok dağınık koda dayalı varsayımlar yapıyorsunuz.

Kodunuzda bulunan ve sonuçlar üzerinde önemli bir etkisi olan bir ton yardımcı hesaplamayı ihmal ediyorsunuz.

 
Renat Fatkhullin :


Hesaplamalarınızın saf bir kanıtı yok, çok dağınık koda dayalı varsayımlar yapıyorsunuz.

Kodunuzda bulunan ve sonuçlar üzerinde önemli bir etkisi olan bir ton yardımcı hesaplamayı ihmal ediyorsunuz.

Sadece sqrt'yi bir diziden basit bir okumaya değiştirerek, genel hesaplama hızının 4 kat düştüğünü görüyorum. Ve her pikselin bu oldukça büyük hesaplamasında sqrt'nin toplam payının %10'u, hatta birkaç %'sini aşması pek olası değildir.

Açık bir anomali!

Bir dizi öğesine erişim süresinin sqrt zamanından 10 kat daha fazla olduğunu söylerken bile bir hata yaptım. Sqrt'nin çok hızlı olduğu ve genel yavaşlamanın çok büyük olduğu göz önüne alındığında çok daha fazlası.

 
Nikolai Semko :

Sadece sqrt'yi bir diziden basit bir okumaya değiştirerek, genel hesaplama hızının 4 kat düştüğünü görüyorum. Ve her pikselin bu oldukça büyük hesaplamasında sqrt'nin toplam payının %10'u, hatta birkaç %'sini aşması pek olası değildir.

Açık bir anomali!

nedenini açıkladım. 1990'ların matematik optimizasyonları artık çalışmıyor.

Ancak, gerçekten berbat koda dayanarak aşağıdaki ifadeleri yapmaya devam ediyorsunuz. Fabrika hatalı.

Bu teknik saflık düzeyinde, konuları tartışmayacağım.

 
Renat Fatkhullin :

nedenini açıkladım. 1990'ların matematik optimizasyonları artık çalışmıyor.

Ancak, gerçekten berbat koda dayanarak aşağıdaki ifadeleri yapmaya devam ediyorsunuz. Fabrika hatalı.

Bu teknik saflık düzeyinde, konuları tartışmayacağım.

Ne tür bir matematik optimizasyonundan bahsettiğini anlamıyorum. Ve herhangi bir açıklama yapmadım, sadece merak ettim - frenlerin kaynağı nedir.

Bu orijinal koddaki çöp ve optimizasyon nerede?

 #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();
  }

Bu daha çok yönlü kodu kullanabilirsiniz, ancak döngülerin ve dizilerin kullanılması nedeniyle görüntüyü çerçeveleme hızı neredeyse yarı yarıya azalır:

 #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();
  }
//+------------------------------------------------------------------+
 

Matematik optimizasyonu: sqrt yerine dizileri kullanmaya çalışmak.

Dağınıklığı görmüyorsunuz ve bu, performans testi kurallarının yanlış anlaşılmasının köküdür. Önceden hesaplanmış diziye karşı hesaplamayı test ediyorsanız, gereksiz tüm öğeleri kaldırmanız gerekir. Kesinlikle her şey gereksiz.

Bir sürü açıklama yaptın. Metinleri alıcının yanından okuyabilmeniz ve onları yazarın çalışmayan korumalarından temizleyebilmeniz gerekir.

 
Renat Fatkhullin :

Matematik optimizasyonu: sqrt yerine dizileri kullanmaya çalışmak.

Evet Tanrı bu sqrt ile. Bu özel işlev durumunda, bunun bir anlamı olmadığını zaten anladım. Denemenin neresi yanlış? Ama şimdi biliyorum.

Bu arada, aynı örnekte, h[] dizisini kullanmak, sin() kullanmak yerine iyi bir hız kazancı sağlar.

Soru zaten bir başkasında:

Büyük bir dizinin hücrelerine erişim kullanılırken, bir görüntü çerçevesinin hesaplama süresi, yalnızca yüzde birkaç olması beklenirken neden birkaç kat artıyor?

Dağınıklığı görmüyorsunuz ve bu, performans testi kurallarının yanlış anlaşılmasının köküdür.   Önceden hesaplanmış diziye karşı hesaplamayı test ediyorsanız, gereksiz tüm öğeleri kaldırmanız gerekir. Kesinlikle her şey gereksiz.

Biliyor musun Renat, senden bir tokat almak hiç de utanılacak bir şey değil, hatta bir onur sayılabilir.

Anladığım kadarıyla çöp, çıkarılabilen ve çıkarılması gereken gereksiz bir şeydir. Ancak bu durumda kaldırılacak bir şey yoktur, aksi takdirde kod çalışmayı durduracaktır.

" Önceden hesaplanmış diziye karşı hesaplamayı" test etmiyorum, ancak çerçeveleme oranını analiz ediyorum.

Evet ve benim durumumda test gerekli değil, çünkü zayıf dizüstü bilgisayarımda ve test etmeden saniyede 25 kare ile saniyede 6 kare arasındaki farkı görebilirsiniz.

Bir sürü açıklama yaptın. Metinleri alıcının yanından okuyabilmeniz ve onları yazarın çalışmayan korumalarından temizleyebilmeniz gerekir.

Sadece birkaç varsayımda bulundum, ancak açıklama yapmadım:

- "SQRT[x] dizisinden okumanın sqrt(x) işlevinden daha hızlı olduğunu varsaymak mantıklıdır."

- " Derleyicinin garip bir şekilde büyük bir diziye eriştiği ve döngünün her yinelemesinde diziyi "unuttuğu" ve her seferinde kendi tür hizmet indekslemeyi yürüttüğü varsayılabilir. "

Ama yine de kendi kendini yetiştirmiş bir programcı olmama rağmen, büyük deneyime sahip kendi kendini yetiştirmiş biri olduğum ve işlemci içinde meydana gelen süreçler hakkında bir şeyler anladığım gerçeğinden dolayı bir açıklama yapmaya cesaret ediyorum, çünkü bir zaman vardı Numega SoftIce benim en sevdiğim programdı, bu sayede montajcı düzeyinde tonlarca başkasının kodunu kürekledim.

- Sizi temin ederim ki, derleyicinizde dizilere erişim açısından (belki de sadece yeterince büyük bir dizi ile kendini gösterir), ekibiniz bu yönde bir çaba vektörü yaparlarsa kolayca bulabilecekleri bir algoritmik söve vardır. Ve örneğim size yardımcı olacaktır.

Hatta tartışabilirim. ))

 

Bir döngüdeki bir tablo üzerinde yineleme yaptığınızda, sonraki her erişimde, bu büyük olasılıkla işlemcinin önbelleğindedir. Bu nedenle daha hızlı çalışır.

Çağrılar arasında bazı kodlar varsa, büyük olasılıkla bir önbellek kaçırma olacaktır. Bu aynı zamanda büyük ve küçük bir masa ile çalışmanın farkını da açıklar.

Ayrıca, açık olmayan başka durumlar da var. Bu nedenle, kodun sadeleştirilmemiş son versiyonunu test etmek gerekir.

 
Beyler, işlev şablonlarında enum türünde bir işlevin çağrıldığını nasıl belirleyeceğimi söyleyin ???
 
Vladimir Pastushak :
Beyler, işlev şablonlarında enum türünde bir işlevin çağrıldığını nasıl belirleyeceğimi söyleyin ???
enum bir tamsayı numaralandırmadır.
0,1,2,3 ..., vb. ...