오류, 버그, 질문 - 페이지 2507

 
Vict :

나는 원래의 아이디어를 염두에 두었습니다(첫 번째 코드에서 주소를 잘못 계산했습니다). 그것이 어렵지 않다면 결과를 보는 것이 흥미로울 것입니다.

발사부터 발사까지 산란이 강하고, 그 차이가 한 방향으로 일정하여 보이지 않습니다. 물론 릴리스 버전을 실행하고 있습니다.

 #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 :
동적 배열 에는 더 많은 검사가 있습니다. Renat은 한 번 썼습니다. 인덱스로 액세스하는 것에 대한 대화에서 게시물을 찾을 수 없습니다. 왜 플러스보다 훨씬 느린가요?

동적 배열을 채울 때 먼저 정적 배열을 채운 다음 ArrayCopy를 동적 배열로 만드는 것이 좋습니다.

 
fxsaber :
이 브레이크는 무엇에서 나온 것입니까?

정적 배열에서 동적 배열 을 만들었습니다. 따라서 모든 결과 문제는 다음과 같습니다.

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

첫 번째 사이클과 두 번째 사이클이 다른 속도로 실행되는 경우.

[삭제]  
fxsaber :

고맙습니다. 물론 이상합니다. 안정적인 차이가 있습니다.

 
Vict :

고맙습니다. 물론 이상합니다. 안정적인 차이가 있습니다.

저도 별반 차이가 없습니다.
 
fxsaber :

동적 배열을 채울 때 먼저 정적 배열을 채운 다음 ArrayCopy를 동적 배열로 만드는 것이 좋습니다.

그리고 있다!

 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 :

그리고 있다!

음, 일반적으로 한 번 초기화되며 대부분 속도에 대해 걱정할 필요가 없습니다. (추가 메모리 오버헤드)

그러나 인덱스에 대한 지속적인 액세스가 있고 배열의 최대 크기가 알려진 경우의 99.9%라고 가정해 봅시다. 동적 배열을 대체하기 위해 정적 배열 주위에 간단한 래퍼를 작성하는 것이 합리적일 수 있습니다.

 
TheXpert :

음, 일반적으로 한 번 초기화되며 대부분 속도에 대해 걱정할 필요가 없습니다. (추가 메모리 오버헤드)

틱을 파싱할 때 녹음 속도가 느려집니다. 그 수가 수천만 개이므로 중요합니다.

그러나 인덱스에 대한 지속적인 액세스가 있고 배열의 최대 크기가 알려진 경우의 99.9%라고 가정해 봅시다. 동적 배열을 대체하기 위해 정적 배열 주위에 간단한 래퍼를 작성하는 것이 합리적일 수 있습니다.

읽을 때 래퍼를 수행하는 것이 합리적일 수 있습니다.


위협 읽기 속도를 높이지 못했습니다.

 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 :

그리고 있다!

내 fillarray1이 약간 더 빠릅니다.

그리고 읽기에 문제가 있다

 
TheXpert :

내 fillarray1이 약간 더 빠릅니다.

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

릴리스 버전을 실행하고 있습니다. 최적화가 활성화되었습니다.