Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make OnCalculate() function in Custom Indicator use GPU in MQL5 / OpenCL?

I have created an Indicator using MQL5.

After Profiling, the program I read that 99% of my CPU is used by my OnCalculate().

Here is my function:

int OnCalculate( const int     rates_total,
                 const int     prev_calculated,
                 const int     begin,
                 const double &price[]
                 )
  {
//--- check for bars count
      float tempprice[];
      ArrayResize( tempprice, ArraySize( price ) );
      if (  rates_total <  InpMAPeriod - 1 + begin ) return( 0 ); // not enough bars for calculation
//--- first calculation or number of bars was changed
      if (  prev_calculated == 0 ) ArrayInitialize( ExtLineBuffer, 0 );

      ArrayCopy( tempprice, price );
//--- sets first bar from what index will be draw
      PlotIndexSetInteger( 0, PLOT_DRAW_BEGIN, InpMAPeriod - 1 + begin );

      switch( InpMAMethod )
      {
         case MODE_EMA:  Execute_Me( price,
                                    "CalculateEMA",
                                     rates_total,
                                     prev_calculated,
                                     begin
                                     );
                         break;
         case MODE_LWMA: Execute_Me( price,
                                    "CalculateLWMA",
                                     rates_total,
                                     prev_calculated,
                                     begin
                                     );
                         break;
         case MODE_SMMA: Execute_Me( price,
                                    "CalculateSmoothedMA",
                                     rates_total,
                                     prev_calculated,
                                     begin
                                     );
                         break;
         case MODE_SMA:  Execute_Me( price,
                                    "CalculateSimpleMA",
                                     rates_total,
                                     prev_calculated,
                                     begin
                                     );
                         break;
     }
     return( rates_total );
  }

Here is the result of profiling: profiling result

Kindly, let me know, how I can make the OnCalculate() work on GPU instead of CPU.

like image 283
Jaffer Wilson Avatar asked Oct 16 '22 19:10

Jaffer Wilson


1 Answers

Which compute device, i.e. whether or not your program uses the CPU can be controlled via the CLContextCreate call:

int CLContextCreate(int device)

Where device could be e.g. CL_USE_GPU_ONLY, or a specific device number.

How to find out the number is described here.


However: What I can see from the profile is, that most of the time is spent Creating and Freeing OpenCL contexts. If the profile represents some kind of call stack, I'd assume that an OpenCL context is created and freed for every computation instead of doing it once during program initialisation and deinitialisation.

This seems to cost you 85 % of your runtime. So make sure, that you create OpenCL Context, Program, Kernel and Buffer objects during initialisation. For repeating computations, you only need do set kernel arguments, read/write buffer objects, and enqueue the kernel for execution

Hope that helps.

like image 158
noma Avatar answered Dec 23 '22 20:12

noma