Hatalar, hatalar, sorular - sayfa 2507

 
Vict :

Aklıma orijinal fikri getirdim (ilk kodda adresleri yanlış saydım). Zorlaştırmıyorsa, sonucu sizin için görmek ilginç olacaktır.

Dağılım, fırlatmadan fırlatmaya güçlü, fark bir yönde sabit, görünmez. Tabii ki, Sürüm sürümünü çalıştırıyorum.

 #define WRONG_ALIGNED
#define CACHE_LINE_SIZE 64

struct Data {
#ifdef WRONG_ALIGNED
   ushort pad;
#else
   uint pad;
#endif
   uint ar[CACHE_LINE_SIZE/ sizeof ( int )+ 1 ];
};

#import "msvcrt.dll"
   long memcpy( uint &, uint &, long );
#import
#define getaddr(x) memcpy(x, x, 0 )

void OnStart ()
{
//   Data data[32768];
   Data data[];
  
   ArrayResize (data, 32768 ); // для не static-массива жуткие тормоза выходят. 
   ZeroMemory (data);
   
   ulong start_time = GetMicrosecondCount ();
   
   for ( unsigned i = 0 ; i < 10000 ; ++ i) {
     for ( int j = ArraySize (data) - 1 ; j >= 0 ; j--)
    {
         int index = int (CACHE_LINE_SIZE - getaddr(data[j].ar[ 0 ]) % CACHE_LINE_SIZE) / sizeof ( int );
         ++ data[j].ar[index];
         ++ data[j].pad;
      }
   }
      
   Alert ( GetMicrosecondCount () - start_time);
   
//   Print(data[100].ar[0]);
//   Print(data[100].pad);
}
 
TheXpert :
dinamik bir dizinin daha fazla kontrolü var, Renat bir keresinde yazmıştı, bir gönderi bulamıyorum, sadece dizine göre erişim hakkında bir konuşmada, neden artılardan çok daha yavaş

Dinamik dizileri doldururken, önce statik olanları doldurmanın ve ardından ArrayCopy'yi dinamik dizilere dönüştürmenin daha iyi olduğu ortaya çıktı.

 
fxsaber :
Bu frenler ne için?

Statik bir diziden dinamik bir dizi yaptınız. Dolayısıyla ortaya çıkan tüm problemler:

 int a[][ 100 ];
ArrayResize (a, 100 );
ZeroMemory (a);

// Первый цикл
for ( int i; i < 100 ; ++i)
{
         for ( int n; n < 100 ; ++n)
        {
                a[i][n]++;
        }
}

// Второй цикл
for ( int n; n < 100 ; ++n)
{
         for ( int i; i < 100 ; ++i)
        {
                a[i][n]++;
        }
}

Birinci ve ikinci döngüler farklı hızlarda çalıştığında.

 
fxsaber :

Teşekkür ederim. Garip tabii. Stabil bir farkım var.

 
Vict :

Teşekkür ederim. Garip tabii. Kararlı bir farkım var.

Bende de fark yok.
 
fxsaber :

Dinamik dizileri doldururken, önce statik olanları doldurmanın ve ardından ArrayCopy'yi dinamik dizilere dönüştürmenin daha iyi olduğu ortaya çıktı.

Ve orada!

 void FillArray1( int &Array[] )
{
   const int Size = ArraySize (Array);
  
   for ( int i = 0 ; i < Size; i++)
    Array[i] = i;
}

#define ARRAY_SIZE 10000

void FillArray2( int &Array[] )
{
   int ArrayStatic[ARRAY_SIZE];
  
   const int Size = ArraySize (Array);
  
   for ( int i = 0 ; i < Size;)
  {
     const int Size2 = i + ARRAY_SIZE < Size ? ARRAY_SIZE : Size - i;
    
     for ( int j = 0 ; j < Size2; j++)
      ArrayStatic[j] = i++;
      
     if (Size2)
       ArrayCopy (Array, ArrayStatic, i - Size2, 0 , Size2);
  }
}

#define BENCH(A)                                                               \
{                                                                              \
   const ulong _StartTime = GetMicrosecondCount ();                              \
  A;                                                                           \
   Print ( "Time[" + #A + "] = " + ( string )( GetMicrosecondCount () - _StartTime)); \
}

void OnStart ()
{
   int Array1[];
   ArrayResize (Array1, 1 e7);

   int Array2[];
   ArrayResize (Array2, 1 e7);
  
  BENCH(FillArray1(Array1));
  BENCH(FillArray2(Array2));
}
 
fxsaber :

Ve orada!

peki, genellikle bir kez başlatılır ve çoğu zaman hız konusunda endişelenmenize gerek yoktur. (artı bellek yükü)

ancak dizinlere sürekli erişim varsa ve vakaların ~ %99,9'unda dizinin maksimum boyutu biliniyorsa, dinamik diziyi değiştirmek için statik bir dizinin etrafına kendi basit sarmalayıcınızı yazmak mantıklı olabilir.

 
TheXpert :

peki, genellikle bir kez başlatılır ve çoğu zaman hız konusunda endişelenmenize gerek yoktur. (artı bellek yükü)

Keneler ayrıştırılırken kaydım yavaşlıyor. On milyonlarca var, bu yüzden önemli.

ancak dizinlere sürekli erişim varsa ve vakaların ~ %99,9'unda dizinin maksimum boyutu biliniyorsa, dinamik diziyi değiştirmek için statik bir dizinin etrafına kendi basit sarmalayıcınızı yazmak mantıklı olabilir.

Okurken bir sarmalayıcı yapmanın mantıklı olması mümkündür.


Tehdit Okuma hızlanamadı

 long ArraySum1( int &Array[] )
{
   long Sum = 0 ;
  
   const int Size = ArraySize (Array);
  
   for ( int i = 0 ; i < Size; i++)
    Sum += Array[i];
    
   return (Sum);
}

#define ARRAY_SIZE 100000

long ArraySum2( int &Array[] )
{
   long Sum = 0 ;

   const int Size = ArraySize (Array);  
  
   int ArrayStatic[ARRAY_SIZE];  
  
   for ( int i = 0 ; i < Size;)
  {
     const int Size2 = i + ARRAY_SIZE < Size ? ARRAY_SIZE : Size - i;

     ArrayCopy (ArrayStatic, Array, 0 , i, Size2);
    
     for ( int j = 0 ; j < Size2; j++)
      Sum += ArrayStatic[j];
      
    i += Size2;
  }
  
   return (Sum);
}

#define BENCH(A)                                                               \
{                                                                              \
   const ulong _StartTime = GetMicrosecondCount ();                              \
  A;                                                                           \
   Print ( "Time[" + #A + "] = " + ( string )( GetMicrosecondCount () - _StartTime)); \
}

void OnStart ()
{
   int Array[];
   ArrayResize (Array, 1 e8);
   ArrayInitialize (Array, 1 );
      
  BENCH( Print (ArraySum1(Array)));
  BENCH( Print (ArraySum2(Array)));
}
 
fxsaber :

Ve orada!

benim fillarray1 biraz daha hızlı

ve okumada sorun var

 
TheXpert :

benim fillarray1 biraz daha hızlı

Time[FillArray1(Array1)] = 39501
Time[FillArray2(Array2)] = 30304

Yayın sürümünü çalıştırıyorum. Optimizasyon etkinleştirildi.