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

 
Renat Fatkhullin :


코드를 잘 확인해보자. 진짜 이유가 뭔지 알아가는 재미가 쏠쏠하다.

시원한! 고맙습니다! 나도 관심 있어.

그리고 sqrt는 정말 매우 빠릅니다. 나노초 미만 :)). 공상!

 
Nikolai Semko :

정적 배열을 시도했습니다. 동일한 것입니다.

sqrt만큼 빠르지만 이 함수가 단순히 배열 요소 를 읽는 것보다 10배 더 빠를 수 있다고 믿기 어렵습니다.

현재 많은 오래된 최적화 기술이 더 이상 작동하지 않습니다.


또한 내 예에서 캔버스 크기가 50x50으로 축소된 경우(이 경우 입력 매개변수 크기가 있으므로 0 대신 50을 설정해야 함)

배열이 훨씬 작아지면(5000개 요소) 속도 그림이 눈에 띄게 바뀝니다. 더 이상 그렇게 강한 대조는 없습니다.

그러나 나에게 명확하지 않습니다 . 요소에 대한 액세스 속도는 배열의 크기에 따라 달라 집니까?

계산에 대한 순수한 증거는 없으며 매우 지저분한 코드를 기반으로 가정하고 있습니다.

코드에 있고 결과에 상당한 영향을 미치는 수많은 보조 계산을 무시하고 있습니다.

 
Renat Fatkhullin :


계산에 대한 순수한 증거는 없으며 매우 지저분한 코드를 기반으로 가정하고 있습니다.

코드에 있고 결과에 상당한 영향을 미치는 수많은 보조 계산을 무시하고 있습니다.

sqrt를 어레이에서 단순 읽기로 변경하는 것만으로도 전체 계산 속도가 4배 감소한다는 것을 알 수 있습니다. 그리고 각 픽셀의 이 다소 큰 계산에서 sqrt의 총 점유율은 10% 또는 몇 %를 초과하지 않을 것입니다.

명백한 변칙!

배열 요소 에 대한 액세스 시간이 sqrt 시간의 10배라고 말하는 것도 실수입니다. sqrt가 너무 빠르고 전반적인 감속이 너무 크다는 점을 감안할 때 훨씬 더.

 
Nikolai Semko :

sqrt를 어레이에서 단순 읽기로 변경하는 것만으로도 전체 계산 속도가 4배 감소한다는 것을 알 수 있습니다. 그리고 각 픽셀의 이 다소 큰 계산에서 sqrt의 총 점유율은 10% 또는 몇 %를 초과하지 않을 것입니다.

명백한 변칙!

나는 그 이유를 설명했다. 1990년대의 수학 최적화는 더 이상 작동하지 않습니다.

하지만 정말 엉망인 코드를 기반으로 다음과 같은 문장을 계속 만들고 있습니다. 공장 오류.

이 수준의 기술적 [un]순도에서는 문제에 대해 논의하지 않겠습니다.

 
Renat Fatkhullin :

나는 그 이유를 설명했다. 1990년대의 수학 최적화는 더 이상 작동하지 않습니다.

하지만 정말 엉망인 코드를 기반으로 다음과 같은 문장을 계속 만들고 있습니다. 공장 오류.

이 수준의 기술적 [un]순도에서는 문제에 대해 논의하지 않겠습니다.

나는 당신이 말하는 수학 최적화의 종류를 이해하지 못합니다. 그리고 나는 어떤 진술도하지 않았지만 브레이크의 근원이 무엇인지 궁금합니다.

이 원본 코드에서 쓰레기와 최적화는 어디에 있습니까?

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

이 더 다양한 코드를 사용할 수 있지만 루프와 배열을 사용하기 때문에 이미지 프레이밍 속도가 거의 절반으로 줄어듭니다.

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

수학 최적화: sqrt 대신 배열을 사용하려고 합니다.

당신은 혼란을 볼 수 없으며 이것이 성능 테스트 규칙에 대한 오해의 근원입니다. 미리 계산된 배열 대 계산을 테스트하는 경우 불필요한 모든 것을 제거해야 합니다. 절대적으로 모든 것이 불필요합니다.

많은 발언을 하셨습니다. 수신자 측에서 텍스트를 읽고 작성자의 작동하지 않는 보호를 해제할 수 있어야 합니다.

 
Renat Fatkhullin :

수학 최적화: sqrt 대신 배열을 사용하려고 합니다.

네, 이 sqrt와 함께 하나님. 이 특정 기능의 경우에는 이것에 의미가 없다는 것을 이미 이해했습니다. 노력하는게 뭐가 문제야? 하지만 지금은 알고 있습니다.

그런데 같은 예에서 h[] 배열을 사용하면 sin() 을 사용하는 대신 적절한 속도 이득을 얻을 수 있습니다.

질문은 이미 다른 질문에 있습니다.

큰 배열의 셀에 대한 액세스를 사용할 때 이미지 프레임의 계산 시간이 몇 퍼센트에 불과할 것으로 예상되는 데 몇 배 증가하는 이유는 무엇입니까?

당신은 혼란을 볼 수 없으며 이것이 성능 테스트 규칙에 대한 오해의 근원입니다.   미리 계산된 배열 대 계산을 테스트하는 경우 불필요한 모든 것을 제거해야 합니다. 절대적으로 모든 것이 불필요합니다.

알다시피, 레나트, 뺨을 맞는 것은 전혀 부끄러운 일이 아니지만 영광으로 여겨질 수도 있다.

내가 이해하기로는 쓰레기는 제거할 수 있고 제거해야 하는 불필요한 것입니다. 그러나 이 경우 제거할 것이 없습니다. 그렇지 않으면 코드가 작동을 멈춥니다.

나는 " 미리 계산된 배열 대 계산"을 테스트하는 것이 아니라 프레이밍 속도를 분석하고 있습니다.

예, 제 경우에는 테스트가 필요하지 않습니다. 약한 랩톱 에서 테스트하지 않고 초당 25프레임과 초당 6프레임의 차이를 볼 수 있기 때문입니다.

많은 발언을 하셨습니다. 수신자 측에서 텍스트를 읽고 작성자의 작동하지 않는 보호를 해제할 수 있어야 합니다.

나는 몇 가지 가정만 했을 뿐 어떤 진술도 하지 않았습니다.

- "SQRT[x] 배열에서 읽는 것이 sqrt(x) 함수보다 빠르다고 가정하는 것이 논리적입니다."

- " 컴파일러가 이상한 방식으로 큰 배열에 액세스하고 루프가 반복될 때마다 배열에 대해 "잊어버리는" 것처럼 보이고 매번 고유한 종류의 서비스 인덱싱을 수행한다고 가정할 수 있습니다. "

그러나 나는 독학 프로그래머이지만 독학으로 많은 경험을 가지고 있고 프로세서 내부에서 일어나는 프로세스에 대해 어느 정도 이해하고 있기 때문에 여전히 감히 말을 할 수 있습니다. SoftIce 는 내가 가장 좋아하는 프로그램이었고 덕분에 어셈블러 수준에서 다른 사람의 수많은 코드를 삽질했습니다.

- 배열에 대한 액세스 측면에서 컴파일러에 알고리즘 잼이 있음을 보장합니다(아마도 충분히 큰 배열에서만 나타날 수 있음). 팀이 이 방향으로 노력 벡터를 만들면 쉽게 찾을 수 있습니다. 그리고 제 모범 이 도움이 될 것입니다.

논쟁도 할 수 있습니다. ))

 

루프의 테이블을 반복할 때마다 후속 액세스는 프로세서의 캐시에 있을 가능성이 큽니다. 따라서 더 빠르게 작동합니다.

호출 사이에 일부 코드가 있으면 캐시 누락이 있을 가능성이 큽니다. 이것은 또한 크고 작은 테이블 작업의 차이점을 설명합니다.

그 외에도 불분명한 사례가 있다. 따라서 코드의 단순화되지 않은 최종 버전을 테스트해야 합니다.

 
얘들 아, enum 유형의 함수가 호출 되는지 함수 템플릿에서 결정하는 방법을 알려주십시오 ???
 
Vladimir Pastushak :
얘들 아, enum 유형의 함수가 호출 되는지 함수 템플릿에서 결정하는 방법을 알려주십시오 ???
열거형은 정수 열거형입니다.
0,1,2,3 ... 등 ...