İşte herhangi bir DLL olmadan doğrudan MetaTrader 5 terminalinde OpenCL ile yapabilecekleriniz - sayfa 18

 
Aleksei Grebenkin :

Renat Fatkhullin, MQL5+OpenCL'de yazma olasılığını görüşmek için sizinle nasıl iletişime geçileceğini. video kartlarının bilgi işlem gücünü kullanmak gereklidir. Her şeyi doğru anlarsam, uygulamadan bir örnek kullanarak: yazılı robot, yerel bir ağ üzerinden bağlı 3 makine tarafından yalnızca 11 parametreyi optimize eder, süre sadece 1 yıl 6 saattir. Tam bir veri sayımı ile 5 yıllık optimizasyonu şarj etmeye çalıştım, bana 2 ay beklemem gerektiğini gösterdi. Doğru anladıysam OpenCL bu sorunu çözüyor . işlemciler değil, video kartları hesaplamalara dahil olacağından hız yüzlerce kez artmalıdır. yani tüm ticaret sistemi dikkate alındığında ayarlarda yaklaşık 200-300 parametre olacaktır. Robotun OpenCL'de yürütüldüğü 3-5 yıllık bir süre için böyle bir hesaplama hacmi, makinelerimden biri tarafından birkaç dakika veya saat içinde yapılacaktır. Doğru mu anladım ve böyle bir robot yazmayı sizinle tartışmak mümkün mü?

OpenCL hesaplamaları, optimizasyon sürecinin paralelleştirilmesine katılmaz.

OpenCL yardımıyla algoritmanın özel olarak hazırlanmış belirli bir bölümünü daha hızlı ve paralel olarak hesaplayabilirsiniz. OpenCL hakkında birçok makalemiz ve tartışmamız var .

 
Maxim Kuznetsov # :

Daha büyük bir kart satın almanızı engelleyen nedir?

bazı iplik A100 https://www.nvidia.com/ru-ru/data-center/a100/

Daha erken olmaz dedi ve bitirdi.




Gforce RTX2080 TI'de önceki hesaplamalardan X2-X3 hızlandırma

Ama test cihazında sinir ağı olan modelleri test eden herkes için ayrı bir nokta var.

OpenCl, 10-12'den fazla işlem (aracı) varsa, çok iş parçacıklı erişim sırasında cihazın yakalanmasına izin vermez.

Özellikle farklı verileri bir arada bir arada analiz etmek için aynı anda birkaç sinir ağı oluşturulduysa.

Ve şu anda sunucuda 96 mantıksal işlemci olmasına rağmen, 12 tanesi hala kullanımda.

Bu nedenle, bir dereceye kadar, ağdan birkaç eski bilgisayara sahip olmak daha karlı, muhtemelen bazen daha ucuzdur.


Ayrı olarak, CPU'nun OpenCL ile kullanılmasına izin veren AMD SDK paketini kurmak için ayrı bir fırsat olduğunu belirtmek isterim.

Artık görevi aynı hızda tamamlamaya hazır 96 cihaz var, ancak artık sadece kartın gücüne bağlı değil.



Ancak, cihaz seçim sürecinden beri OpenCl kitaplığını düzeltmek zorunda kaldım.

CLContextCreate(CL_USE_ANY)

hangi cihazın yüklü olduğunu anlamayı mümkün kılmaz.

Ve sadece GPU'yu veya sadece CPU'yu seçmek, her iki seçeneği de aynı anda kullanmayı mümkün kılmaz.


Bu sorunu çözmek için, her kartı mevcut hesaplama hızı için test ettim,

hesaplamayı simüle etmek için bu ilginç örneği kullanmak (güzel)

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


kütüphane kodunda şu şekilde somutlaştırıldı:

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

danışman kodunda

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

OpenCL kitaplığında, bir cihaz seçme olasılığını hesaba katın.

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

Yarınki sürümde, makine öğreniminde kullanılmak üzere normal matris/vektör veri türlerini yayınlıyoruz.

MQL5 programlarının kodu büyük ölçüde basitleştirilecek ve çok çeşitli matematiksel işlemlerin uygulanmasına izin verecektir.

Bu, işlevselliğin ilk neslidir ve ardından TensorFlow gibi paketlerin yeteneklerini uygulamak için daha karmaşık mekanizmalar uygulayacağız. OpenCL'nin kullanışlı olduğu yer burasıdır.

 
Yeni bir çağın geçişi, önceki geçişin sonuçlarına dayanması gerektiğinde, bir sinir ağı için tüm bu çoklu iş parçacığının anlamı nedir? Ve tüm paralel iş parçacıkları sadece ilkinin sonuçlarını tekrarlayacaktır. Ve sonunda sonucu tek bir dosyada dolduracaklar. Önceki iş parçacığının sonuçlarının üzerine yazmak, ancak esasen değeri değiştirmemek...
 
Dmytryi Voitukhov # :
Yeni bir çağın geçişi, önceki geçişin sonuçlarına dayanması gerektiğinde, bir sinir ağı için tüm bu çoklu iş parçacığının anlamı nedir? Ve tüm paralel iş parçacıkları sadece ilkinin sonuçlarını tekrarlayacaktır. Ve sonunda, sonucu tek bir dosyada dolduracaklar. Önceki iş parçacığının sonuçlarının üzerine yazmak, ancak esasen değeri değiştirmemek...

Renat haykırıyor ve sen sızlanıyorsun. Kaç yaşındasın?

 

Kütüphaneyi biraz düzeltti, güzelleştirdi

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


Dosyalar:
Neden: