DLLを使わずにMetaTrader 5で直接OpenCLを使ってできることは次のとおりです。 - ページ 18

 
Aleksei Grebenkin:

私は正しく理解している場合は、練習から例を使用して:書かれたロボットは、ローカルネットワークに接続されている3台で11パラメータのみを最適化し、期間はわずか1年6時間です。私はデータのフル検索で最適化のために5年を充電しようとしましたが、それは2ヶ月待たなければならないことを私に示した。もし私が正しく理解していれば、OpenCLが問題を解決して くれるでしょう。 計算はプロセッサではなくビデオカードで行われるので、速度は数百倍になるはずです。 つまり、取引システム全体を考慮すると、200〜300程度のパラメータが設定されることになります。

OpenCLの計算は、最適化処理の並列化には関与しません。

OpenCLを使えば、アルゴリズムの特定部分をより高速に、並列に計算することができます。OpenCLについては、多くの記事や議論が あります。

 
Maxim Kuznetsov #:

大きなカードを買わずに済むのはなぜ?

some A100https://www.nvidia.com/ru-ru/data-center/a100/

言い尽くされていますね。




Gforce RTX2080 TIでの過去の計算によるX2-X3加速度

しかし、テスターでニューラルネットワークモデルをテストする人には、別のポイントがあります。

OpenClでは、10~12個以上のプロセス(エージェント)がある場合、マルチスレッドでのアクセスはできません。

特に、複数のニューラルネットワークを同時に作成して、異なるデータを1つに統合して分析する場合。

そして、サーバーには現在96個の論理プロセッサがあるにもかかわらず、12個を使わなければならない。

したがって、ネットワークから古いコンピュータを何台も持ってきた方が、おそらく何倍も安くつくのです。


また、別途、AMD SDKをインストールすることで、OpenCLでCPUを使用できるようになる機会もありましたので、ご紹介しておきます。

今、96台のデバイスが同じスピードでタスクを実行する準備ができていますが、カードのパワーだけに頼っているわけではありません。



しかし、OpenClライブラリはデバイスの選択処理があるため、修正する必要がありました

CLContextCreate(CL_USE_ANY)

は、現在どのデバイスがロードされているかを把握することができません。

また、GPUのみ、CPUのみを選択すると、両方のオプションを同時に使用することはできません。


この問題を解決するために、私は各カードの現在の計算速度のテストを行いました。

計算のシミュレーションをするために、この興味深い例を使っています。

https://www.mql5.com/ru/code/825


ライブラリのコードでは、次のように具体化されています。

int COpenCL::ID_FasterDevice()
  {
 
   int cl_prg;
   int cl_krn;
   int cl_mem;
   int cl_ctx;
   string device;
   ulong speed [];
   
   int dCount= (int)CLGetInfoInteger(0,CL_DEVICE_COUNT);
  
   
   if (dCount>1)
   {
   ArrayResize(speed,dCount);
   
      //----------------- измерим текщую производительность и выберем более быстрый девайс ----------
      for(int i = 0; i<dCount;i++)
         {
         cl_ctx=i;
         CLGetInfoString(cl_ctx,CL_DEVICE_NAME,device);
         Print(cl_ctx,": ",device);
         ulong start_time=GetMicrosecondCount();
     
//--- initializing OpenCL objects
   if((cl_ctx=CLContextCreate())==INVALID_HANDLE)
     {
      Print("OpenCL not found");
      return -1;
     }
   if((cl_prg=CLProgramCreate(cl_ctx,cl_src))==INVALID_HANDLE)
     {
      CLContextFree(cl_ctx);
      Print("OpenCL program create failed");
      return -1;
     }
   if((cl_krn=CLKernelCreate(cl_prg,"MFractal"))==INVALID_HANDLE)
     {
      CLProgramFree(cl_prg);
      CLContextFree(cl_ctx);
      Print("OpenCL kernel create failed");
      return -1;
     }
   if((cl_mem=CLBufferCreate(cl_ctx,SIZE_X*SIZE_Y*sizeof(uint),CL_MEM_READ_WRITE))==INVALID_HANDLE)
     {
      CLKernelFree(cl_krn);
      CLProgramFree(cl_prg);
      CLContextFree(cl_ctx);
      Print("OpenCL buffer create failed");
      return -1;
     }
//--- getting ready for execution
   float x0       =-2;
   float y0       =-0.5;
   float x1       =-1;
   float y1       = 0.5;
   uint  max      = 20000;
   uint  offset[2]={0,0};
   uint  work  [2]={SIZE_X,SIZE_Y};
   string objname ="OpenCL_"+IntegerToString(ChartID());
   string resname ="::Mandelbrot_"+IntegerToString(ChartID());
//--- setting unchangeable OpenCL function parameters
   CLSetKernelArg(cl_krn,4,max);
   CLSetKernelArgMem(cl_krn,5,cl_mem);
//--- creating the object for graphics display
   ChartRedraw();
   Comment("Benchmark OpenCl devices");
   ObjectCreate(0,objname,OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetInteger(0,objname,OBJPROP_XDISTANCE,4);
   ObjectSetInteger(0,objname,OBJPROP_YDISTANCE,26);
//--- create initial empty picture
   uint buf[];

   ArrayResize(buf,SIZE_X*SIZE_Y);
   ResourceCreate(resname,buf,SIZE_X,SIZE_Y,0,0,SIZE_X,COLOR_FORMAT_XRGB_NOALPHA);
   ObjectSetString(0,objname,OBJPROP_BMPFILE,resname);
//--- rendering, till we are not stopped from the outside
   for (int samples=0;samples<100;samples++)
     {
      uint x=GetTickCount();
      //--- setting floating parameters
      CLSetKernelArg(cl_krn,0,x0);
      CLSetKernelArg(cl_krn,1,y0);
      CLSetKernelArg(cl_krn,2,x1);
      CLSetKernelArg(cl_krn,3,y1);
      //--- rendering the frame
      CLExecute(cl_krn,2,offset,work);
      //--- taking the frame data
      CLBufferRead(cl_mem,buf);
      //--- outputting the rendering time
      Comment(IntegerToString(GetTickCount()-x)+" msec per frame");
      //--- saving the frame in memory and drawing it
      ResourceCreate(resname,buf,SIZE_X,SIZE_Y,0,0,SIZE_X,COLOR_FORMAT_XRGB_NOALPHA);
      ChartRedraw();
      //--- a small pause and parameters update for the next frame
      Sleep(10);
      x0+=0.001 f;
      x1-=0.001 f;
      y0+=0.001 f;
      y1-=0.001 f;
     
     }
//--- removing OpenCL objects
   CLBufferFree(cl_mem);
   CLKernelFree(cl_krn);
   
   CLProgramFree(cl_prg);
   CLContextFree(cl_ctx);
         ulong finishtime=GetMicrosecondCount();
         ulong testtime= finishtime-start_time;  
         speed [i] = testtime; 
         
   ObjectDelete(0,objname);
   Comment("");
     }
      
      m_context= ArrayMinimum(speed,0,WHOLE_ARRAY);
   }
   else 
      m_context=-1;
//--- remove object
  
   return m_context;
  }
//+------------------------------------------------------------------+

EAコードで

 COpenCL         *TestOpenCL;
      TestOpenCL =new COpenCL;
      int faster_device=TestOpenCL.ID_FasterDevice();
      TestOpenCL.Initialize(cl_program,id_device,true);         

OpenCL ライブラリでは、デバイスを選択する可能性を考慮すること

//+------------------------------------------------------------------+
//| Initialize                                                       |
//+------------------------------------------------------------------+
bool COpenCL::Initialize(const string program,const int id_device=-1,const bool show_log=true)
  {  
   
     
     m_context=id_device;
    
     if((m_context=CLContextCreate())==INVALID_HANDLE)
     {
      Print("OpenCL not found");      
     }   
     else if ((m_context=CLContextCreate(CL_USE_ANY))==INVALID_HANDLE)
         {
       
               Print("OpenCL not found. Error code=",GetLastError());
                  return(false);     
         }
ファイル:
 

明日のリリースでは、機械学習で使用するためのインハウスの行列/ベクトルデータ 型をリリースします。

MQL5のプログラムのコードは、よりシンプルになり、多くの数学的演算を実装することができるようになります。

これは第一世代の機能で、その後、TensorFlowなどのパッケージの機能を実現するために、より複雑な仕組みを実装していく予定です。その際に便利なのがOpenCLです。

 
新しいエポックの通過が前の通過の結果に依存しなければならないのに、ニューラルネットワークのためにこれほどまでにマルチスレッドを行う意味があるのだろうか。そして、すべての並列スレッドは、最初のスレッドの結果を繰り返すだけである。そして、最終的には1つのファイルに結果を預けることになる。前スレの結果を上書きするも、要するに値を変えずに...。
 
Dmytryi Voitukhov #:
新しいエポックの通過は、前の通過の結果に基づいて行われるべきなのに、ニューラルネットワークのためにこれほどまでにマルチスレッドを行う意味はあるのだろうか。そして、すべての並列スレッドは、最初のスレッドの結果を繰り返すだけである。そして、最終的には1つのファイルに結果を預けることになる。前スレの結果を上書きするも、要するに値を変えずに...。

レナートが叫ぶと、あなたは泣き言を言う。あなたは何歳ですか?

 

ライブラリーを若干修正し、より美しくしました。

       double testtime= (GetTickCount()-start_time)/1000;  
         speed [i] = NormalizeDouble(MathRound(1000/testtime/8)*8,3); //NormalizeDouble(1000/testtime,2); 
      
      CLGetInfoString(i,CL_DEVICE_NAME,device);
       Print("Device #", i,", speed =",speed [i]," FPS. ",device); 
   ObjectDelete(0,objname);
   Comment("");
     }
      
      m_context= ArrayMaximum(speed,0,WHOLE_ARRAY);
      CLGetInfoString(m_context,CL_DEVICE_NAME,device);
     
      Print("Faster device: #",m_context,", ",device," "); 


ファイル: