以下是你可以在MetaTrader 5中直接使用OpenCL而不需要任何DLLs的情况 - 页 18

 
Aleksei Grebenkin:

Renat Fatkhullin 我如何与你联系,讨论用MQL5+OpenCL编写的可能性。我需要使用视频卡的处理能力。如果我理解正确,那么用实践中的一个例子:编写的机器人通过本地网络连接的3台机器只优化了11个参数,周期只有1年6小时。如果我没有理解错的话,OpenCL将解决这个问题。 速度应该增加数百倍,因为计算将不涉及处理器而涉及显卡。 这意味着,考虑到整个交易系统,在设置中会有大约200-300个参数。

OpenCL的计算不参与优化过程的并行化。

通过OpenCL,你可以更快地并行计算算法的特定部分。我们有很多关于OpenCL的文章和讨论

 
Maxim Kuznetsov #:

是什么阻止了你购买更大的卡?

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

已经说过了,也做过了。




在Gforce RTX2080 TI上进行的X2-X3加速,来自于之前的计算

但对于在测试器中测试神经网络模型的人来说,还有另外一点。

如果有10-12个以上的进程(代理),OpenCl不允许多线程访问。

特别是如果同时创建多个神经网络来分析不同的数据,并将其合并在一起。

而且,尽管服务器现在有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将在这方面派上用场。

 
当一个新纪元的通过必须依赖于前一个纪元的结果时,所有这些多线程对神经网络的意义是什么?而所有的并行线程只会重复第一个线程的结果。最后,他们将把结果存入一个文件中。覆盖了前一个主题的结果,但实质上没有改变价值...
 
Dmytryi Voitukhov #:
对于一个神经网络来说,所有这些多线程的意义是什么呢,因为一个新纪元的通道应该是基于前一个通道的结果。而所有的并行线程只会重复第一个线程的结果。最后,他们将把结果存入一个文件中。覆盖了前一个主题的结果,但实质上没有改变价值...

雷纳特感叹道,而你则发牢骚。你多大了?

 

对库进行了一点调整,做得很美。

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


附加的文件: