Hier sehen Sie, was Sie mit OpenCL direkt in MetaTrader 5 ohne DLLs machen können - Seite 18

 
Aleksei Grebenkin:

Renat Fatkhullin, wie kann ich mit Ihnen Kontakt aufnehmen, um die Möglichkeit des Schreibens in MQL5+OpenCL zu besprechen. ich muss die Rechenleistung von Videokarten nutzen. wenn ich richtig verstehe, dann mit einem Beispiel aus der Praxis: der geschriebene Roboter optimiert nur 11 Parameter von 3 Maschinen, die über ein lokales Netzwerk verbunden sind, der Zeitraum ist nur 1 Jahr 6 Stunden. ich habe versucht, 5 Jahre Optimierung mit einer vollständigen Suche von Daten zu berechnen, es zeigte mir, dass 2 Monate warten müssen.Wenn ich es richtig verstanden habe, wird OpenCL das Problem lösen. Die Geschwindigkeit sollte sich um das Hundertfache erhöhen, da die Berechnungen nicht mit Prozessoren, sondern mit Grafikkarten durchgeführt werden. Das bedeutet, dass unter Berücksichtigung des gesamten Handelssystems etwa 200-300 Parameter in den Einstellungen vorhanden sein werden.

OpenCL-Berechnungen sind nicht an der Parallelisierung des Optimierungsprozesses beteiligt.

Mit OpenCL können Sie einen bestimmten Teil des Algorithmus schneller und parallel berechnen. Wir haben viele Artikel und Diskussionen über OpenCL.

 
Maxim Kuznetsov #:

Was hindert Sie daran, eine größere Karte zu kaufen?

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

Es ist gesagt und getan worden.




X2-X3-Beschleunigung aus früheren Berechnungen auf Gforce RTX2080 TI

Aber es gibt noch einen weiteren Punkt für alle, die Modelle neuronaler Netze im Tester testen.

OpenCl erlaubt keinen Multithreading-Zugriff, wenn es mehr als 10-12 Prozesse (Agenten) gibt.

Vor allem dann, wenn mehrere neuronale Netze gleichzeitig erstellt werden, um verschiedene Daten zu analysieren und in einem zu verschmelzen.

Und obwohl der Server jetzt 96 logische Prozessoren hat, müssen wir 12 verwenden.

Daher ist es rentabler, mehrere alte Computer aus dem Netz zu nehmen, wahrscheinlich um ein Vielfaches billiger.


Unabhängig davon möchte ich die Möglichkeit erwähnen, das AMD SDK zu installieren, das die Verwendung von CPUs mit OpenCL ermöglicht.

Jetzt gibt es 96 Geräte, die eine Aufgabe mit der gleichen Geschwindigkeit ausführen können, aber nicht nur von der Leistung der Karte abhängig sind.



Die OpenCl-Bibliothek musste jedoch korrigiert werden, da der Prozess der Geräteauswahl

CLContextCreate(CL_USE_ANY)

erlaubt es nicht zu verstehen, welches Gerät gerade geladen ist.

Und wenn Sie nur GPU oder nur CPU auswählen, können Sie nicht beide Optionen gleichzeitig verwenden.


Um dieses Problem zu lösen, habe ich jede Karte auf ihre aktuelle Rechengeschwindigkeit getestet,

anhand dieses interessanten Beispiels die Berechnung zu simulieren (nett)

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


Im Bibliothekscode ist sie wie folgt verankert

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

im EA-Code

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

Berücksichtigen Sie in der OpenCL-Bibliothek die Möglichkeit, das Gerät auszuwählen

//+------------------------------------------------------------------+
//| 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);     
         }
Dateien:
 

In der morgigen Version werden wir hauseigene Matrix/Vektor-Datentypen für die Verwendung im maschinellen Lernen freigeben.

Der Code von MQL5-Programmen wird sehr viel einfacher und ermöglicht es uns, eine große Anzahl von mathematischen Operationen durchzuführen.

Dies ist die erste Generation der Funktionalität und dann werden wir komplexere Mechanismen implementieren, um die Fähigkeiten von Paketen wie TensorFlow zu implementieren. OpenCL wird sich dabei als nützlich erweisen.

 
Was nützt all dieses Multithreading einem neuronalen Netz, wenn der Durchlauf einer neuen Epoche auf den Ergebnissen eines früheren Durchlaufs beruhen muss. Und alle parallelen Threads wiederholen nur die Ergebnisse des ersten Threads. Und am Ende werden sie die Ergebnisse in einer Datei ablegen. Überschreiben Sie die Ergebnisse des vorherigen Threads, aber im Wesentlichen ohne den Wert zu ändern...
 
Dmytryi Voitukhov #:
Welchen Sinn hat all dieses Multithreading für ein neuronales Netz, wenn der Durchlauf einer neuen Epoche auf den Ergebnissen des vorangegangenen Durchlaufs beruhen sollte. Und alle parallelen Threads wiederholen nur die Ergebnisse des ersten Threads. Und am Ende werden sie die Ergebnisse in einer Datei ablegen. Überschreiben Sie die Ergebnisse des vorherigen Threads, aber im Wesentlichen ohne den Wert zu ändern...

ruft Renat und du jammerst. Wie alt sind Sie?

 

Die Bibliothek wurde leicht korrigiert, um sie zu verschönern.

       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," "); 


Dateien: