Используете ли вы возможности OpenCL для ускорения расчетов? (и обсуждение применения в торговле) - страница 6

 
Реter Konow:

Хорошо. Подготовительные операции понятны.

Основные расчетные операции.

Функция TrigFitOCL() является в некотором роде посредником между MQL программой и программой OpenCL.

Её MQL интерфейс аналогичен функции TrigFit(), используемой для расчетов средствами MQL без использования OpenCL.

А её интерфейсом со стороны кернел-программы является последовательность функций управляющих передачей данных,

запуском кернел-программы, и получением данных из кернела.

Функция TrigFitOCL() выполняется многократно, в цикле и содержит следующие операции обращения к кернелу:

1. Установка в качестве параметра c номером 0 функции OpenCL (кернела) буфера по хендлу h_CL_Buffers[0]: CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffers[0])

и аналогичные команды назначения буферов для параметров функции кернела. Параметры кернела нумеруются подряд и их количество может

не быть равно количеству буферов (некоторые входные параметры передаются без использования буферов). Буферизованные значения передаются по ссылке.

Я не смог найти способа возвращать значения простых (не структурных) типов из кернела, кроме как через использования массива из одного элемента.

Поэтому для таких переменных тоже назначаются буфера.

2. Установка в качестве 2-го параметра функции OpenCL (кернела) значения переменной n: CLSetKernelArg(h_CL_Kernel,2,n)

и аналогичные команды установки значений переменных простого типа.

Значения передаются непосредственно (не по ссылке) и доступны в кернеле сразу после установки параметра.

3. Запись исходные значений переменных структурных типов (массивов) в буфера указанные по хендлу h_CL_Buffers[],

для получения доступа к этим значениям из кернела: CLBufferWrite(h_CL_Buffers[0],x,0,0,n).

Для простых переменных такая запись не требуется.

4. Запуск выполнения кернела: CLExecute(h_CL_Kernel).

5. Считывание результатов расчета в массивы: CLBufferRead(h_CL_Buffers[0],x,0,0,n) - считывание n-элементов в массив x и др.

Завершающие операции.

Нужны для освобождения использованных кернел-программой ресурсов, после завершения программы или в случае ошибки на одном из этапов подготовки и выполнения.

Выполняются в обратном порядке к подготовительным операциям.

В данном примере все завершающие операции собраны в функции ShutDown():

Освобождение памяти буферов: CLBufferFree(i_CL_Buffers[i]).

Освобождение памяти кернела: CLKernelFree(i_CL_Kernel).

Освобождение ресурсов программы: CLProgramFree(i_CL_Program).

Освобождение ресурсов устройства (оборудования, контекста): CLContextFree(i_CL_Context).

 

Полезно для прочтения:

Overview about OpenCL and parallel processing

http://www.cmsoft.com.br/opencl-tutorial/overview-opencl-parallel-processing/

Overview about OpenCL and parallel processing
Overview about OpenCL and parallel processing
  • www.cmsoft.com.br
Let’s get a basic overview about how OpenCL works. Take a look at the simplified scheme below: You can see that there is a HOST and there are DEVICES. A closer look allows you to notice that the host sends information to the devices, sends execution commands and retrieves data. How does that work? The HOST executes the code you write as usual...
 

Основные положения и примеры программ занесены в публичный проект LibreOCL.

 

Вот допустим, у меня скрипт есть, который считает разные статистические параметры на каждом баре относительно МА и +-пункты , при этом значения MA перебираются, по идеи это можно запараллелить, может что-то подобное покажите как сделать?

 
Aleksey Vyazmikin:

Вот допустим, у меня скрипт есть, который считает разные статистические параметры на каждом баре относительно МА и +-пункты , при этом значения MA перебираются, по идеи это можно запараллелить, может что-то подобное покажите как сделать?

Посмотрите в каталог примеров OpenCL:



 
Renat Fatkhullin:

Посмотрите в каталог примеров OpenCL:



Какой конкретно пример посмотреть, или это в целом предложение?
 
Aleksey Vyazmikin:
Какой конкретно пример посмотреть, или это в целом предложение?

Просто как примеры посмотрите.

Возможно, что-то подойдет и вообще поймете в каком направлении двигаться.

 
Renat Fatkhullin:

Просто как примеры посмотрите.

Возможно, что-то подойдет и вообще поймете в каком направлении двигаться.


Спасибо.

 
Renat Fatkhullin:

Просто как примеры посмотрите.

Возможно, что-то подойдет и вообще поймете в каком направлении двигаться.


Почему функция CLGetInfoInteger(0,CL_DEVICE_COUNT) детектирует не все имеющиеся устройства OpenCL?

01

02

void OnStart(){ 
//---  
   int dCount=(int)CLGetInfoInteger(0,CL_DEVICE_COUNT);
   Print("dCount =",dCount); 
   string Result; 
   {for(int i=0;i<dCount;i++) 
   { 
      int clCtx=CLContextCreate(i); 
      {if(clCtx==-1) 
      {
         Print("============== DEVICE "+IntegerToString(i)+": ERROR in CLContextCreate"+" ================="); 
      }else{
         Print("============== DEVICE "+IntegerToString(i)+" ================="); 
         //--- Get Info String
         Result="";
         CLGetInfoString(clCtx,CL_DEVICE_NAME,Result); 
         Print("DEVICE_NAME=",Result); 
      }}//if(clCtx==-1)
   }}//for(int i=0;i<dCount;i++) 
}//OnStart()
//

03

То есть графическая карта, которую видят все тестовые программы, начиная с одного из последних релизов в mql5 скрыта?

 

Выяснилось, что в тестере стратегий в режиме визуализации OpenCL работает только на центральном процессоре.

При старте терминала обнаруживаются 3 OpenCL устройства:

2018.01.02 09:39:19.040 OpenCL  Device #0: GPU Advanced Micro Devices, Inc. Pitcairn with OpenCL 1.2 (16 units, 1170 MHz, 1024 Mb, version 1348.5 (VM))
2018.01.02 09:39:19.040 OpenCL  Device #1: CPU GenuineIntel Intel(R) Core(TM)2 Duo CPU E8400 @ 3.00GHz with OpenCL 1.2 (2 units, 3000 MHz, 4094 Mb, version 1348.5 (sse2))
2018.01.02 09:39:19.040 OpenCL  Device #2: CPU Intel(R) Corporation Intel(R) Core(TM)2 Duo CPU E8400 @ 3.00GHz with OpenCL 1.2 (2 units, 3000 MHz, 4094 Mb, version 4.5.0.8)

При запуске примитивного теста:

void OnInit(){ 
//---  
   int dCount=(int)CLGetInfoInteger(0,CL_DEVICE_COUNT);
   Print("dCount =",dCount); 
   string Result; 
   {for(int i=0;i<dCount;i++) 
   { 
      ResetLastError();
      int clCtx=CLContextCreate(i); 
      //int clCtx=CLContextCreate(CL_USE_ANY); 
      {if(clCtx==-1) 
      {
         Print("============== DEVICE "+IntegerToString(i)+": ERROR in CLContextCreate="+IntegerToString(GetLastError())+" ================="); 
      }else{
         Print("============== DEVICE "+IntegerToString(i)+" ================="); 
         //--- Get Info String
         Result="";
         CLGetInfoString(clCtx,CL_DEVICE_NAME,Result); 
         Print("DEVICE_NAME=",Result); 
      }}//if(clCtx==-1)
   }}//for(int i=0;i<dCount;i++) 
}//OnInit()

Получаем результат обнаружения OpenCL устройств в реалтайме:

2018.01.02 10:33:47.843 OCL_TST_Exp_02 (EURUSD,M1)      dCount =3
2018.01.02 10:33:47.852 OCL_TST_Exp_02 (EURUSD,M1)      ============== DEVICE 0 =================
2018.01.02 10:33:47.852 OCL_TST_Exp_02 (EURUSD,M1)      DEVICE_NAME=Pitcairn
2018.01.02 10:33:47.862 OCL_TST_Exp_02 (EURUSD,M1)      ============== DEVICE 1 =================
2018.01.02 10:33:47.862 OCL_TST_Exp_02 (EURUSD,M1)      DEVICE_NAME=Intel(R) Core(TM)2 Duo CPU     E8400  @ 3.00GHz
2018.01.02 10:33:47.862 OCL_TST_Exp_02 (EURUSD,M1)      ============== DEVICE 2: ERROR in CLContextCreate=5103 =================

То есть третье устройство не инициализируется (не создается контекст).

При запуске того же теста в тестере стратегий (режим визуализации):

2018.01.02 10:38:35.130 2017.12.25 00:00:00   dCount =1
2018.01.02 10:38:35.139 2017.12.25 00:00:00   ============== DEVICE 0 =================
2018.01.02 10:38:35.139 2017.12.25 00:00:00   DEVICE_NAME=Intel(R) Core(TM)2 Duo CPU     E8400  @ 3.00GHz

То есть обнаруживается всего одно OpenCL устройство - центральный процессор.