エラー、バグ、質問 - ページ 655

 
Urain:

このコードはグラフィックカードの性能テストに使えるのでしょうか?

いいえ。まず、1ページあたり数百万個のオブジェクトを追加する必要があります。そして、loop(10000){ChartRedraw(); }とします。

:)

 
MetaDriver:

なーんだ。まず、1ページあたり数百万個のオブジェクトを追加する必要があります。そして、loop(10000){ ChartRedraw(); }とします。

:)

数百万は多すぎるが、テストなら10万で十分だ。

#property script_show_inputs
input uint Count=1000;
input uint CountObj=100000;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   long ChId=ChartID(); 
   for(int i=0;i<CountObj;i++)
     {
      ObjHLine(ChId,i,1.+(i/(double)CountObj));
     }
   uint st=GetTickCount();
   for(uint i=0; i<Count; i++)ChartRedraw();
   Alert("Count ChartRedraw()=",Count," time=",GetTickCount()-st," mk.c.");
   ObjectsDeleteAll(ChId,0,OBJ_HLINE);
  }
//+------------------------------------------------------------------+
void ObjHLine(ulong chart_id,string name,double price)
  {   
   ENUM_OBJECT  type=OBJ_HLINE; // тип объекта  
   int          nwin=0;                   // индекс окна   
//---
   if(ObjectFind(chart_id,name)<0)
      ObjectCreate(chart_id,name,type,nwin,0,0,0,0);
   ObjectSetInteger(chart_id,name,OBJPROP_COLOR,clrGreen);
   ObjectSetDouble(chart_id,name,OBJPROP_PRICE,price);
  }
//+------------------------------------------------------------------+

MT5のビデオカード適合性の客観的テスト」とでも言えばいいのでしょうか?

あるいは、オブジェクトの値も変更する必要があるのでは?

 
Urain:

数百万は多すぎるが、テストなら10万で十分だ。

mt5の客観的なビデオカードテストということでよろしいでしょうか?

なんて書いてあるんだ?:) しています。

2012.02.27 19:04:09 CardTest(Urain) (EURUSD,H1) CountChartRedraw()=1000 at time=26224 ms

 
MetaDriver:

なんて書いてあるんだ、俺のだ

2012.02.27 19:04:09 CardTest(Urain) (EURUSD,H1) Count ChartRedraw()=1000 at time=26224 ms


オブジェクトの一部を再描画して、CPUとビデオカードを指定してみよう。 開発者が拒否しなければ、ブランチを作ってみんなでデータを投稿すればいいんだ。以下は、オブジェクトの一部を再描画したコードです。

#property script_show_inputs
input uint Count=1000;
input uint CountObj=100000;
input uint CountObjRedrawt=1000;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   long ChId=ChartID();
   uint sto,eno,reso;

   for(int i=0;i<CountObj;i++)
     {
      ObjHLine(ChId,i,1.+(i/(double)CountObj));
     }
   sto=GetTickCount();
   for(int i=0;i<CountObjRedrawt;i++)
      ObjectSetDouble(ChId,rand()%CountObj,OBJPROP_PRICE,1.+((i+1)/(double)CountObj));
   eno=GetTickCount();
   reso=eno-sto;

    uint st=GetTickCount();
   for(uint i=0; i<Count; i++)
     {
      if(i%2==0)
        {
         for(int j=0;j<CountObjRedrawt;j++)
            ObjectSetDouble(ChId,rand()%CountObj,OBJPROP_PRICE,1.+((i+2)/(double)CountObj));
        }
      else
        {
         for(int j=0;j<CountObjRedrawt;j++)
            ObjectSetDouble(ChId,rand()%CountObj,OBJPROP_PRICE,1.+((i+1)/(double)CountObj));
        }
      ChartRedraw();
     }
   Alert("ChartRedraw() Count=",Count," CountObj=",CountObj," CountObjRedrawt=",CountObjRedrawt," time=",GetTickCount()-st-(reso*Count)," mk.c.");
   ObjectsDeleteAll(ChId,0,OBJ_HLINE);
  }
//+------------------------------------------------------------------+
void ObjHLine(ulong chart_id,string name,double price)
  {
   ENUM_OBJECT  type=OBJ_HLINE; // тип объекта  
   int          nwin=0;                   // индекс окна   
//---
   if(ObjectFind(chart_id,name)<0)
      ObjectCreate(chart_id,name,type,nwin,0,0,0,0);
   ObjectSetInteger(chart_id,name,OBJPROP_COLOR,clrGreen);
   ObjectSetDouble(chart_id,name,OBJPROP_PRICE,price);
  }
//+------------------------------------------------------------------+

ここでは、どのような設定で見えていたプリントをより多く書き換えています。

おっと、内部カウンターはjに変更する必要がありますね。

 

書いています。

Test VideoCart (EURUSD,M15)     ChartRedraw() Count=1000 CountObj=100000 CountObjRedrawt=1000 time=24859 mk.c.
Проц P4 3 Гц, RAM 3 Гб
Видяха NVIDIA Corporation GeForce GT 430 with OpenCL 1.1 (2 units, 1400 MHz, 1023 Mb, version 295.73)
 
Urain:

オブジェクトの一部を再描画し、CPUとビデオカードを指定してみよう。 開発者が拒否しなければ、ブランチを作って希望者全員がデータを投稿すればいい。以下は、オブジェクトの一部を再描画したコードです。

このテストは、オブジェクトとの非同期通信キュー(ObjectSetXXXX関数)の速度をよりテストするもので、ビデオシステムのテストではありません。
 
Renat:
このテストは、ビデオシステムではなく、オブジェクトとの非同期通信キュー(ObjectSetXXXX関数)の速度をよりテストするものです。

主張するわけではありませんが、もしかしたら、テスト開始前に、物体を変化させる周期的な時間を計測し、その後、合計からその時間の倍数を差し引くことに気づかなかったかもしれません。

   sto=GetTickCount();
   for(int i=0;i<CountObjRedrawt;i++)
      ObjectSetDouble(ChId,rand()%CountObj,OBJPROP_PRICE,1.+((i+1)/(double)CountObj));
   eno=GetTickCount();
   reso=eno-sto;
...
   " time=",GetTickCount()-st-(reso*Count)

間違っていたら訂正してください。

SZY ユニークなことに、私はif(i%2=0)を割り引かないのですが、このテストによって数値が大きく変わるとは思っていません。

ちなみに、再描画をしなくても同じような測定値が得られています。これは、ObjectSetXXXXX関数を頻繁に使用すると、その作業が何らかの形で加速され、時間控除が若干過大評価されているのだと思われます。

 
Urain:

書いています。

今はこんな感じです。

2012.02.27 19:37:44    gpu_Test (Urain) (EURUSD,M30)    ChartRedraw() Count=1000 CountObj=100000 CountObjRedrawt=1000 time=22792 mk.c.

CPU: AuthenticAMD AMD Phenom(tm) II X6 1100T Processor with OpenCL 1.1 (6 units, 3840 MHz, 16345 Mb, version 2.0)
GPU: Advanced Micro Devices, Inc. Cayman with OpenCL 1.1 (20 units, 750 MHz, 1024 Mb, version CAL 1.4.1664 (VM))


しかし、これは真っ白な画面での話です。こんな時(上のディスプレイは512行、下のディスプレイは同じ)。


となると、こんな感じです。

2012.02.27 19:47:53    gpu_Test (Urain) (EURUSD,M1)    ChartRedraw() Count=1000 CountObj=100000 CountObjRedrawt=1000 time=123022 mk.c.

そして、インジケータ自体は、この時GPUに負荷をかけず(CPUでゼロバーで計算)、このすべての混乱のターミナルレンダリングにのみ負荷をかけます。
 
Urain:

主張するわけではありませんが、もしかしたら、テスト開始前に、物体を変化させる周期的な時間を計測し、その後、合計からその時間の倍数を差し引くことに気づかなかったかもしれません。

そうですね、補正操作があることにすぐには気がつきませんでした。

しかし、それでも私の訂正は全く正しいのです。非同期キュー(実際にはキューである)の速度は、キューの動作モードに直接依存する。

まず、外部からの刺激がなく、キューからの読み取り操作もない状態で、書き込み1回あたりの速度を測定しましたね。実際、一瞬で終わりました(reso=0ms、ご自身でお確かめください)。しかし、テストでは書き込みだけでなくChartRedrawによる 読み込み操作も使うようになり、校正のためのキューがブロックされたり、すべての操作が重なったりするようになったんですね。

実際には、既存の10万個のオブジェクトのうち、1,000個のオブジェクトについて、1,000,000回の変更を行うテストです。ObjectXXXxの関数を使ったビデオテストと言うのはありえない。

 
Renat:

そうですね、補正操作があることにすぐには気がつきませんでした。

しかし、それでも私の訂正は全く正しいのです。非同期キュー(実際にはキューである)の速度は、それを処理するモードに直接依存する。

まず、外部からの刺激がなく、キューからの読み取り操作もない状態で、書き込み1回あたりの速度を測定しましたね。実際、一瞬で終わりました(reso=0ms、ご自身でお確かめください)。しかし、テストでは書き込みだけでなくChartRedrawによる読み込み操作も使うようになり、校正のためのキューがブロックされたり、すべての操作が重なったりするようになったんですね。

実際には、既存の10万個のオブジェクトのうち、1,000個のオブジェクトについて、1,000,000回の変更を行うテストです。これではObjectXXXxの関数を使った映像テストとは言えません。

また、最初にChartRedraw なしでリペイントのフルセットを測定し、次にChartRedraw ありで測定し、減算を行えば正しいでしょうか?

ところで、このトピックは非常に適切で、テストを書くことができます、それはあなたがmqlの内部構造を知るために簡単です。

#property script_show_inputs
input uint Count=1000;
input uint CountObj=100000;
input uint CountObjRedrawt=1000;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   long ChId=ChartID();
   uint sto,eno,reso;

   for(int i=0;i<CountObj;i++)
     {
      ObjHLine(ChId,i,1.+(i/(double)CountObj));
     }
   sto=GetTickCount();// замерим время вычета
   for(uint i=0; i<Count; i++)
     {
      if(i%2==0)
        {
         for(int j=0;j<CountObjRedrawt;j++)
            ObjectSetDouble(ChId,rand()%CountObj,OBJPROP_PRICE,1.2+((i+2)/(double)CountObj));
        }
      else
        {
         for(int j=0;j<CountObjRedrawt;j++)
            ObjectSetDouble(ChId,rand()%CountObj,OBJPROP_PRICE,1.2+((i+1)/(double)CountObj));
        }      
     }
   for(int i=0;i<CountObj;i++)// вернём всё в исходное состояние
     {
      ObjectSetDouble(ChId,i,OBJPROP_PRICE,1.+(i/(double)CountObj));
     }     
   eno=GetTickCount();
   reso=eno-sto;
   
   uint st=GetTickCount();
   for(uint i=0; i<Count; i++)
     {
      if(i%2==0)
        {
         for(int j=0;j<CountObjRedrawt;j++)
            ObjectSetDouble(ChId,rand()%CountObj,OBJPROP_PRICE,1.2+((i+2)/(double)CountObj));
        }
      else
        {
         for(int j=0;j<CountObjRedrawt;j++)
            ObjectSetDouble(ChId,rand()%CountObj,OBJPROP_PRICE,1.2+((i+1)/(double)CountObj));
        }
      ChartRedraw();
     }
   Alert("ChartRedraw() Count=",Count," CountObj=",CountObj," CountObjRedrawt=",CountObjRedrawt," time=",GetTickCount()-st-reso," mk.c.");
   ObjectsDeleteAll(ChId,0,OBJ_HLINE);
  }
//+------------------------------------------------------------------+
void ObjHLine(ulong chart_id,string name,double price)
  {
   ENUM_OBJECT  type=OBJ_HLINE; // тип объекта  
   int          nwin=0;                   // индекс окна   
//---
   if(ObjectFind(chart_id,name)<0)
      ObjectCreate(chart_id,name,type,nwin,0,0,0,0);
   ObjectSetInteger(chart_id,name,OBJPROP_COLOR,clrGreen);
   ObjectSetDouble(chart_id,name,OBJPROP_PRICE,price);
  }
//+------------------------------------------------------------------+