Fehler, Irrtümer, Fragen - Seite 2507

 
Vict:

Ich habe die ursprüngliche Idee überarbeitet (der erste Code zählte die Adressen nicht richtig). Wenn es Ihnen nichts ausmacht, wäre es interessant, das Ergebnis mit Ihnen zu sehen.

Sie variiert stark von Lauf zu Lauf, man kann den Unterschied von einer Seite zur anderen nicht erkennen. Natürlich verwende ich die Release-Version.

#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:
Ein dynamisches Array hat mehr Prüfungen, Renat schrieb einmal, ich kann den Beitrag nicht finden, nur über den Index-Zugriff zu sprechen, warum es deutlich langsamer als Pluspunkte ist

Es hat sich herausgestellt, dass es beim Füllen von dynamischen Arrays besser ist, zuerst statische Arrays zu füllen und dann ArrayCopy auf dynamische Arrays anzuwenden.

 
fxsaber:
Was ist die Ursache für diese Verlangsamung?

Sie haben aus einem statischen Array ein dynamisches Ar ray gemacht. Daraus ergeben sich alle Probleme mit dem Typ:

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]++;
        }
}

Wenn die erste und die zweite Schleife mit unterschiedlichen Geschwindigkeiten laufen.

 
fxsaber:

Ich danke Ihnen. Das ist natürlich seltsam. Ich habe einen stabilen Unterschied.

 
Vict:

Ich danke Ihnen. Das ist natürlich seltsam. Ich habe einen stabilen Unterschied.

Ich habe auch keinen Unterschied.
 
fxsaber:

Es hat sich herausgestellt, dass es beim Füllen von dynamischen Arrays besser ist, zuerst statische Arrays zu füllen und dann ArrayCopy auf dynamische Arrays anzuwenden.

So ist es!

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:

Das ist es!

Die Initialisierung ist in der Regel eine einmalige Sache, und in den meisten Fällen müssen Sie sich keine Gedanken über die Geschwindigkeit machen. (plus Speicher-Overhead)

Aber wenn es konstante Referenz durch Indizes und zum Beispiel in ~99,9% der Fälle maximale Größe des Arrays bekannt ist, wahrscheinlich macht es Sinn, Ihre einfache Wrapper um statische Array zu ersetzen dynamische zu schreiben.

 
TheXpert:

Die Initialisierung ist in der Regel eine einmalige Sache, und die meiste Zeit muss man sich keine Gedanken über die Geschwindigkeit machen. (plus Speicher-Overhead).

Ich habe eine Aufzeichnung, die sich beim Parsen von Ticks verlangsamt. Es gibt Dutzende von Millionen von ihnen, also ist es wichtig.

Aber wenn es konstante Referenz durch Indizes und zum Beispiel in ~99,9% Fällen maximale Größe des Arrays bekannt ist, wahrscheinlich ist es sinnvoll, Ihre einfache Wrapper um statische Array anstelle von dynamischen ein zu schreiben.

Es könnte sinnvoll sein, auch einen Wrap on Read zu machen.


SZZ Beim Lesen kann ich keine Beschleunigung erzielen.

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:

Das ist es!

mein fillarray1 ist etwas schneller

und das Lesen ist ein Chaos.

 
TheXpert:

mein fillarray1 ist etwas schneller

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

Die Release-Version läuft. Optimierung aktiviert.