Here's what you can do with OpenCL directly in MetaTrader 5 without any DLLs - page 4

 
Alexey Volchanskiy:
Yes, I'm a bit familiar with OCL, I'm aware of that. You don't have to load the whole EA into the map, let them load some parallel code fragments, they are usually a percentage of the whole code.
That way, you won't get a huge speedup for standard Expert Advisors. Everything will be limited by bandwidth of the agents.
 
Vitalie Postolache:
So, why do I see only CPU cores (Core i5, 8 cores - 8 agents) when optimizing when I have NVIDIA 780GTX?

Do you use OpenCL in your code?

Most likely you think that any of your code should load on the graphics card. Which is not true.

I highly recommend reading our article on OpenCL in MetaTrader 5 where everything is explained in detail how it works:

 

In order to get a significant acceleration, you need to send the entire adviser to the GPU, but for this you need to write your own tester.

Here is an example of such a tester, a neural network with trading logic, OCL code:

//————————————————————————————————————————————————————————————————————————————————————————————————
//Функция для ядра
string GPU_kernel( int hl1NeuronCount,
                   int hl2NeuronCount,
                   int sampleCount,
                   int signalCount)
{
   return
         (
           "#define HL1Count "              + ( string )hl1NeuronCount + "                     \r\n"
           "#define HL2Count "              + ( string )hl2NeuronCount + "                     \r\n"
           //------------------------------------------------------------------------------------
           "#define NeuronSensitivity  "    + ( string )NeuronSensitivity_P + "                \r\n"
           //------------------------------------------------------------------------------------
           "#define sampleCount "           + ( string )sampleCount + "                        \r\n"
           //------------------------------------------------------------------------------------
           "#define signalCount "           + ( string )signalCount + "                        \r\n"
           //------------------------------------------------------------------------------------
           "#define StrArrSaSize "          + ( string )( sizeof (ArrSample) / sizeof ( float )) + "\r\n"
           "typedef struct{float C[StrArrSaSize];} ArrSa;                                   \r\n"
           //------------------------------------------------------------------------------------
           "#define StrArrWeSize "          + ( string )( sizeof (ArrWe) / sizeof ( float )) + "    \r\n"
           "typedef struct{float C[StrArrWeSize];} ArrWe;                                   \r\n"
           //------------------------------------------------------------------------------------
           "#define StrArrCrSize "          + ( string )( sizeof (ArrCr) / sizeof ( float )) + "    \r\n"
           "typedef struct{float C[StrArrCrSize];}ArrCr;                                    \r\n"
           //------------------------------------------------------------------------------------
           "#define Spread "                + ( string )(Spread_P * Point ()) + "               \r\n"
           //------------------------------------------------------------------------------------
           "#define Point "                 + ( string ) Point () + "                            \r\n"
           "#define SL "                    + ( string )(StopLoss_P * Point ()) + "             \r\n"
           "#define TP "                    + ( string )(TakeProfit_P * Point ()) + "           \r\n"
           //------------------------------------------------------------------------------------
           "                                                                                \r\n"
           "__kernel void Work(__global ArrSa *Sample,                                      \r\n"
           "                   __global ArrWe *Weights,                                     \r\n"
           "                   __global ArrCr *Result)                                      \r\n"
           "{                                                                               \r\n"
           "  int thread       = get_global_id(0);                                          \r\n"
           "                                                                                \r\n"
           "  //------------------Переменные нейронной сети---------------------------------\r\n"
           "  float nHL1 [HL1Count];   // Нейроны первого скрытого слоя                     \r\n"
           "  float nHL2 [HL2Count];   // Нейроны второго скрытого слоя                     \r\n"
           "  ArrWe parametr = Weights[thread];  // Параметры системы                       \r\n"
           "  int   cnt_W    = 0;     // счетчик весов                                      \r\n"
           "  float out      = 0.0;   // выход сети                                         \r\n"
           "                                                                                \r\n"
           "  //-------------------Переменные для торговли----------------------------------\r\n"
           "  float temp             = 0.0;    // для временного хранения чего нибудь       \r\n"
           "                                                                                \r\n"
           "  //---параметры цены                                                           \r\n"
           "  float priceASK            = 0.0;   // текущая Ask цена                        \r\n"
           "  float priceBID            = 0.0;   // текущая Bid цена                        \r\n"
           "  float pricePrevHighASK    = 0.0;   // максимум предыдущей свечи Ask           \r\n"
           "  float pricePrevHighBID    = 0.0;   // максимум предыдущей свечи Bid           \r\n"
           "  float pricePrevLowASK     = 0.0;   // минимум предыдущей свечи Ask            \r\n"
           "  float pricePrevLowBID     = 0.0;   // минимум предыдущей свечи Bid            \r\n"
           "                                                                                \r\n"
           "  float posType             = 0.0;   // тип сделки:                             \r\n"
           "                                     // 1.0 - buy,                              \r\n"
           "                                     //-1.0 - sell;                             \r\n"
           "                                     // 0.0 - нет открытой сделки               \r\n"
           "  float posPriceClose       = 0.0;                                              \r\n"
           "  float posPriceClosePrevHi = 0.0;                                              \r\n"
           "  float posPriceClosePrevLo = 0.0;                                              \r\n"
           "                                                                                \r\n"
           "  //-----------------Текущие показатели позиции---------------------------------\r\n"
           "  float posPriceSL          = 0.0;    // цена StopLoss открытой сделки          \r\n"
           "  float posPriceTP          = 0.0;    // цена TakeProfit открытой сделки        \r\n"
           "                                                                                \r\n"
           "  //--------------------Статистика торговли-------------------------------------\r\n"
           "  int   StTradeProfitCount  = 0;      // кол-во приб. сделок                    \r\n"
           "  int   StTradeLossCount    = 0;      // кол-во уб. сделок                      \r\n"
           "                                                                                \r\n"
           "  int   StTradeLossSeries   = 0;     // текущая серия убыточных ордеров         \r\n"
           "  int   StTradeMaxLossSer   = 0;     // самая длинная серия уб.ордеров          \r\n"
           "                                                                                \r\n"
           "  //-----------------------Тут прогон по истории--------------------------------\r\n"
           "  for(int hist = 0;hist < sampleCount;hist++)                                   \r\n"
           "  {                                                                             \r\n"
           "    cnt_W = 0;                                                                  \r\n"
           "    //---------------Обработаем первый скрытый слой-----------------------------\r\n"
           "    //Добавим смещение точек насыщения нейрона: (+b)                            \r\n"
           "    for(int u = 0;u < HL1Count;u++)                                             \r\n"
           "    {                                                                           \r\n"
           "      nHL1[u] = parametr.C[cnt_W];                                              \r\n"
           "      cnt_W++;                                                                  \r\n"
           "    }                                                                           \r\n"
           "                                                                                \r\n"
           "    //Сумма произведений нейронов предыдущего слоя и их весов:                  \r\n"
           "    // (+w1*x1+...+wn*xn) для каждого нейрона                                   \r\n"
           "    for(int u = 0;u < HL1Count;u++)                                             \r\n"
           "    {                                                                           \r\n"
           "      for(int i = 0;i < signalCount;i++)                                        \r\n"
           "      {                                                                         \r\n"
           "        nHL1[u] += Sample[hist].C[i + 3] * parametr.C[cnt_W];                   \r\n"
           "        cnt_W++;                                                                \r\n"
           "      }                                                                         \r\n"
           "    }                                                                           \r\n"
           "                                                                                \r\n"
           "    //Посчитаем функцию активации для каждого скрытого нейрона                  \r\n"
           "    for(int u = 0;u < HL1Count;u++)                                             \r\n"
           "    {                                                                           \r\n"
           "      nHL1[u] = 5.0 * nHL1[u] / (1.0 + fabs(4.02 * nHL1[u]));                   \r\n"
           "    }                                                                           \r\n"
           "                                                                                \r\n"
           "    //---------------Обработаем второй скрытый слой-----------------------------\r\n"
           "    //Добавим смещение точек насыщения нейрона: (+b)                            \r\n"
           "    for(int u = 0;u < HL2Count;u++)                                             \r\n"
           "    {                                                                           \r\n"
           "      nHL2[u] = parametr.C[cnt_W];                                              \r\n"
           "      cnt_W++;                                                                  \r\n"
           "    }                                                                           \r\n"
           "                                                                                \r\n"
          
 

code continuation:

          "    //Сумма произведений нейронов предыдущего слоя и их весов:                  \r\n"
           "    // (+w1*x1+...+wn*xn) для каждого нейрона                                   \r\n"
           "    for(int u = 0;u < HL2Count;u++)                                             \r\n"
           "    {                                                                           \r\n"
           "      for(int i = 0;i < HL1Count;i++)                                           \r\n"
           "      {                                                                         \r\n"
           "        nHL2[u] += nHL1[i] * parametr.C[cnt_W];                                 \r\n"
           "        cnt_W++;                                                                \r\n"
           "      }                                                                         \r\n"
           "    }                                                                           \r\n"
           "                                                                                \r\n"
           "    //Посчитаем функцию активации для каждого скрытого нейрона                  \r\n"
           "    for(int u = 0;u < HL2Count;u++)                                             \r\n"
           "    {                                                                           \r\n"
           "      nHL2[u] = 5.0 * nHL2[u] / (1.0 + fabs(4.02 * nHL2[u]));                   \r\n"
           "    }                                                                           \r\n"
           "                                                                                \r\n"
           "    //-----------------Обработаем выходной слой---------------------------------\r\n"
           "    //Добавим смещение точек насыщения нейрона: (+b)                            \r\n"
           "    out = parametr.C[cnt_W];                                                    \r\n"
           "    cnt_W++;                                                                    \r\n"
           "                                                                                \r\n"
           "    //Сумма произведений нейронов предыдущего слоя и их весов:                  \r\n"
           "    // (+w1*x1+...+wn*xn) для каждого нейрона                                   \r\n"
           "    for(int i = 0;i < HL2Count;i++)                                             \r\n"
           "    {                                                                           \r\n"
           "      out += nHL2[i] * parametr.C[cnt_W];                                       \r\n"
           "      cnt_W++;                                                                  \r\n"
           "    }                                                                           \r\n"
           "    //==========================================================================\r\n"
           "                                                                                \r\n"
           "                                                                                \r\n"
           "    //==========================================================================\r\n"
           "    priceASK         = Sample[hist].C[0] + Spread;                              \r\n"
           "    priceBID         = Sample[hist].C[0];                                       \r\n"
           "                                                                                \r\n"
           "    pricePrevHighASK = Sample[hist].C[1] + Spread;                              \r\n"
           "    pricePrevHighBID = Sample[hist].C[1];                                       \r\n"
           "                                                                                \r\n"
           "    pricePrevLowASK  = Sample[hist].C[2] + Spread;                              \r\n"
           "    pricePrevLowBID  = Sample[hist].C[2];                                       \r\n"
           "                                                                                \r\n"
           "    //-----------------проверка условий на выход из рынка-----------------------\r\n"
           "    // если есть открытая поза                                                  \r\n"
           "    if(posType != 0.0)                                                          \r\n"
           "    {                                                                           \r\n"
           "      if(posType == 1.0)                                                        \r\n"
           "      {                                                                         \r\n"
           "        posPriceClose       = priceBID;                                         \r\n"
           "        posPriceClosePrevHi = pricePrevHighBID;                                 \r\n"
           "        posPriceClosePrevLo = pricePrevLowBID;                                  \r\n"
           "      }                                                                         \r\n"
           "      else                                                                      \r\n"
           "      {                                                                         \r\n"
           "        posPriceClose       = priceASK;                                         \r\n"
           "        posPriceClosePrevHi = pricePrevHighASK;                                 \r\n"
           "        posPriceClosePrevLo = pricePrevLowASK;                                  \r\n"
           "      }                                                                         \r\n"
           "                                                                                \r\n"
           "                                                                                \r\n"
           "      // может уже сработал SL?                                                 \r\n"
           "      if(posType * (posPriceSL - posPriceClose) >= 0.0 ||                       \r\n"
           "         posType * (posPriceSL - posPriceClosePrevLo) >= 0.0)                   \r\n"
           "      {                                                                         \r\n"
           "        // на одну убыточную сделку больше                                      \r\n"
           "        StTradeLossCount++;                                                     \r\n"
           "        // текущая серия убыточных сделок увеличилась                           \r\n"
           "        StTradeLossSeries++;                                                    \r\n"
           "        // если серия уб. сделок больше чем в истори, то запомним               \r\n"
           "        StTradeMaxLossSer = (StTradeMaxLossSer < StTradeLossSeries) ?           \r\n"
           "                            StTradeLossSeries : StTradeMaxLossSer;              \r\n"
           "        // позиция закрыта                                                      \r\n"
           "        posType = 0.0;                                                          \r\n"
           "      }                                                                         \r\n"
           "      // нет, SL не сработал                                                    \r\n"
           "      else                                                                      \r\n"
           "      {                                                                         \r\n"
           "        // может уже сработал TP?                                               \r\n"
           "        if(posType * (posPriceClose - posPriceTP) >= 0.0 ||                     \r\n"
           "           posType * (posPriceClosePrevHi - posPriceTP) >= 0.0)                 \r\n"
           "        {                                                                       \r\n"
           "          // на одну прибыльную сделку больше                                   \r\n"
           "          StTradeProfitCount++;                                                 \r\n"
           "          // текущая серия убыточных сделок закончилась                         \r\n"
           "          StTradeLossSeries = 0;                                                \r\n"
           "          // позиция закрыта                                                    \r\n"
           "          posType = 0.0;                                                        \r\n"
           "        }                                                                       \r\n"
           "      }                                                                         \r\n"
           "                                                                                \r\n"
           "    }                                                                           \r\n"
           "    //--------------------------------------------------------------------------\r\n"
           "                                                                                \r\n"
           "                                                                                \r\n"
           "    //-----------------проверка сигнала на вход в рынок-------------------------\r\n"
           "    // если нет открытых поз проверим возможность открытия                      \r\n"
           "    if(posType == 0.0 && hist < (sampleCount - 1))                              \r\n"
           "    {                                                                           \r\n"
           "      // если есть сигнал на покупку                                            \r\n"
           "      if(NeuronSensitivity < out)                                               \r\n"
           "      {                                                                         \r\n"
           "        posPriceTP   = priceASK + TP;                                           \r\n"
           "        posPriceSL   = priceASK - SL;                                           \r\n"
           "        posType = 1.0;                                                          \r\n"
           "      }                                                                         \r\n"
           "      // если есть сигнал на продажу                                            \r\n"
           "      if(out < -NeuronSensitivity)                                              \r\n"
           "      {                                                                         \r\n"
           "        posPriceSL   = priceBID + SL;                                           \r\n"
           "        posPriceTP   = priceBID - TP;                                           \r\n"
           "        posType = -1.0;                                                         \r\n"
           "      }                                                                         \r\n"
           "    }                                                                           \r\n"
           "  }                                                                             \r\n"
           "                                                                                \r\n"
           "                                                                                \r\n"
           "  //----------------------------------------------------------------------------\r\n"
           "  float Profit = ((float)StTradeProfitCount*TP)-((float)StTradeLossCount*SL);   \r\n"
           "  Result[thread].C[0] =  Profit;                                                \r\n"
           "  Result[thread].C[1] = -StTradeMaxLossSer;                                     \r\n"
           "}                                                                               \r\n"
          );
}
//————————————————————————————————————————————————————————————————————————————————————————————————
 
Renat Fatkhullin:

This is a demonstration not only of GPU calculations in the MQL5 code, but also of the graphical capabilities of the terminal:

The full source code as a script is attached. The bug on OpenCL 1.2 has been fixed.

This is cool! I will make 3d graphics, will come in handy. And the speed will be good for a mega project. I'll come over today and give it a test run.)
 
Andrey Dik:

the continuation of the code:

By the way, is it possible to send code to OCL somehow in the form of a file, rather than as a line item? Otherwise it looks a bit creepy.

 
Alexey Volchanskiy:

By the way, is it possible to send code to OCL not as a line-by-line sheet, but somehow as a file? It looks a bit creepy.

The OCL code is just a string. You can read the file into the string variable and send it to the GPU.
 
It's not working for me(
 

It is important to note that now, at the end of 2016, it is already possible to lay claim to the presence of OpenCL in the target systems.

Even if there is no GPU, OpenCL will run on CPU using all cores. This is what the device set looks like:

OpenCL  Device #0: GPU Advanced Micro Devices, Inc. Hawaii with OpenCL 2.0 (44 units, 1080 MHz, 8192 Mb, version 2117.13 (VM), rating 1760)
OpenCL  Device #1: CPU GenuineIntel Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60 GHz with OpenCL 1.2 (24 units, 2598 MHz, 32680 Mb, version 2117.13 (sse2,avx), rating 85)

The terminal automatically selects the fastest device based on the performance rating. It is also possible to manually select any device via the CLContextCreate function.

Unfortunately, forget about OpenCL on Windows XP. And 32-bit operating systems in general - it's the year 2017.

More unpleasant is the situation with Nvidia, which is essentially sabotaging the OpenCL standard and not implementing OpenCL 2.0. First it sabotaged the implementation of OpenCL 1.2, now OpenCL 2.0. It is doing this to promote its own implementation of CUDA, which hurts the whole community.

Besides, Nvidia deliberately lowers accuracy in its gamer cards to limit their use in mathematics and to stimulate purchases of specialized cards (Tesla).

Against this backdrop AMD looks to be winning not only because of their clearly faster maths (mining farms on AMD are usually built), but also for their open standards strategy(they have very much opened up and are pushing into the public domain). The introduction of OpenCL 2.0 in AMD cards has brought this specification very close to CUDA capabilities and now there is no point in laying the groundwork for CUDA at all.

 
Soon we will allow OpenCL in MQL5 Cloud Network at least for CPU implementations.
Распределенные вычисления в сети MQL5 Cloud Network
Распределенные вычисления в сети MQL5 Cloud Network
  • cloud.mql5.com
Заработать деньги, продавая мощности своего компьютера для сети распределенных вычислений MQL5 Cloud Network
Reason: