OpenCL: MQL5의 내부 구현 테스트

 

우리는 MQL5에서 직접 OpenCL에 대한 기본 지원을 위해 노력하고 있습니다. 몇 가지 빌드에서 공개적으로 사용할 수 있습니다.

다음은 OpenCL에서 Mandelbrot 프랙탈을 계산하는 작은 작업 예입니다. 소프트웨어 구현에 비해 계산 속도가 크게 빨라집니다. OpenCL에서의 계산은 100배 더 빠른 것으로 나타났습니다.


 //+------------------------------------------------------------------+
//|                                                     ocl_test.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link       "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Код функции OpenCL                                               |
//+------------------------------------------------------------------+
const string cl_src=
       "__kernel void MFractal(                                    \r\n"
       "                       float x0,                           \r\n"
       "                       float y0,                           \r\n"
       "                       float x1,                           \r\n"
       "                       float y1,                           \r\n"
       "                       uint  max,                          \r\n"
       "              __global uint *out)                          \r\n"
       "  {                                                        \r\n"
       "   size_t  w = get_global_size(0);                         \r\n"
       "   size_t  h = get_global_size(1);                         \r\n"
       "   size_t gx = get_global_id(0);                           \r\n"
       "   size_t gy = get_global_id(1);                           \r\n"
       "   float dx = x0 + gx * (x1-x0) / (float) w;               \r\n"
       "   float dy = y0 + gy * (y1-y0) / (float)h;                \r\n"
       "   float x  = 0;                                           \r\n"
       "   float y  = 0;                                           \r\n"
       "   float xx = 0;                                           \r\n"
       "   float yy = 0;                                           \r\n"
       "   float xy = 0;                                           \r\n"
       "   uint i = 0;                                             \r\n"
       "   while ((xx+yy)<4 && i<max)                              \r\n"
       "     {                                                     \r\n"
       "      xx = x*x;                                            \r\n"
       "      yy = y*y;                                            \r\n"
       "      xy = x*y;                                            \r\n"
       "      y = xy+xy+dy;                                        \r\n"
       "      x = xx-yy+dx;                                        \r\n"
       "      i++;                                                 \r\n"
       "     }                                                     \r\n"
       "   if(i==max)                                              \r\n"
       "      out[w*gy+gx] = 0;                                    \r\n"
       "   else                                                    \r\n"
       "      out[w*gy+gx] = (uint)((float)0xFFFFFF/(float)max)*i; \r\n"
       "  }                                                        \r\n" ;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#define SIZE_X 512
#define SIZE_Y 512
//+------------------------------------------------------------------+
//| Заголовок BMP файла                                              |
//+------------------------------------------------------------------+
struct BitmapHeader
  {
   ushort             type;
   uint               size;
   uint               reserv;
   uint               offbits;
   uint               imgSSize;
   uint               imgWidth;
   uint               imgHeight;
   ushort             imgPlanes;
   ushort             imgBitCount;
   uint               imgCompression;
   uint               imgSizeImage;
   uint               imgXPelsPerMeter;
   uint               imgYPelsPerMeter;
   uint               imgClrUsed;
   uint               imgClrImportant;
  };
//+------------------------------------------------------------------+
//| Запись битмапа в файл                                            |
//+------------------------------------------------------------------+
bool SaveBitmapToFile( const string filename, uint &bitmap[], const BitmapHeader &info)
  {
//--- откроем файл
   int file= FileOpen (filename, FILE_WRITE | FILE_BIN );
   if (file== INVALID_HANDLE )
     {
       Print ( __FUNCTION__ , " error opening '" ,filename, "'" );
       return ( false );
     }
//--- запишем заголовок и само тело
   if ( FileWriteStruct (file,info)== sizeof (info))
     {
       if ( FileWriteArray (file,bitmap)== ArraySize (bitmap))
        {
         FileClose (file);
         return ( true );
        }
     }
//--- неудачно получилось, удалим файл от греха подальше
   FileClose (file);
   FileDelete (filename);
   Print ( __FUNCTION__ , " error writting '" ,filename, "'" );
//--- вернем ошибку
   return ( false );
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
  {
//--- инициализируем OpenCL объекты
   int cl_ctx=CLContextCreate();
   int cl_prg=CLProgramCreate(cl_ctx,cl_src);
   int cl_krn=CLKernelCreate(cl_prg, "MFractal" );
   int cl_mem=CLBufferCreate(cl_ctx,SIZE_X*SIZE_Y* sizeof ( float ),CL_MEM_READ_WRITE);
//--- подготовимся к выполению
   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};
//--- выставляем неизменяемые параметры функции OpenCL
   CLSetKernelArg(cl_krn, 4 ,max);
   CLSetKernelArgMem(cl_krn, 5 ,cl_mem);
//--- подготовим буфер для вывода пикселей
   uint buf[];  
   ArrayResize (buf,SIZE_X*SIZE_Y);
//--- подготовим заголовок
   BitmapHeader info;
   ZeroMemory (info);
   info.type          = 0x4d42 ;
   info.size          = sizeof (info)+SIZE_X*SIZE_Y* 4 ;
   info.offbits       = sizeof (info);
   info.imgSSize      = 40 ;
   info.imgWidth      =SIZE_X;
   info.imgHeight     =SIZE_Y;
   info.imgPlanes     = 1 ;
   info.imgBitCount   = 32 ;
   info.imgCompression= 0 ;                 // BI_RGB
   info.imgSizeImage  =SIZE_X*SIZE_Y* 4 ;   
//--- создаём объект для вывода графики
   ObjectCreate ( 0 , "x" , OBJ_BITMAP_LABEL , 0 , 0 , 0 );
   ObjectSetInteger ( 0 , "x" , OBJPROP_XDISTANCE , 0 );
   ObjectSetInteger ( 0 , "x" , OBJPROP_YDISTANCE , 50 );
//--- рендерим пока не остоновят снаружи
   while (! IsStopped ())
     {
       uint x= GetTickCount ();
       //--- выставляем плавающие параметры
      CLSetKernelArg(cl_krn, 0 ,x0);
      CLSetKernelArg(cl_krn, 1 ,y0);
      CLSetKernelArg(cl_krn, 2 ,x1);
      CLSetKernelArg(cl_krn, 3 ,y1);
       //--- рендерим кадр
      CLExecute(cl_krn, 2 ,offset,work);                  
       //--- забираем данные кадра
      CLBufferRead(cl_mem,buf);
       //--- выведем время рендера
       Comment ( GetTickCount ()-x);
       //--- сохраняем кадр в памяти и рисуем его
      SaveBitmapToFile( "Mandelbrot.bmp" ,buf,info);
       ObjectSetString ( 0 , "x" , OBJPROP_BMPFILE , NULL );
       ObjectSetString ( 0 , "x" , OBJPROP_BMPFILE , "\\Files\\Mandelbrot.bmp" );
       ChartRedraw ();
       //--- небольшая задержка и обновление параметров для следующего кадра
       Sleep ( 10 );
      x0+= 0.001 f;
      x1-= 0.001 f;
      y0+= 0.001 f;
      y1-= 0.001 f;
     }
//--- удаляем объекты OpenCL
   CLBufferFree(cl_mem);
   CLKernelFree(cl_krn);
   CLProgramFree(cl_prg);
   CLContextFree(cl_ctx);
  }
//+------------------------------------------------------------------+
OpenCL: Мост в параллельные миры
OpenCL: Мост в параллельные миры
  • 2012.05.16
  • Sceptic Philozoff
  • www.mql5.com
В конце января 2012 года компания-разработчик терминала MetaTrader 5 анонсировала нативную поддержку OpenCL в MQL5. В статье на конкретном примере изложены основы программирования на OpenCL в среде MQL5 и приведены несколько примеров "наивной" оптимизации программы по быстродействию.
 
Renat :

우리는 MQL5에서 직접 OpenCL에 대한 기본 지원을 위해 노력하고 있습니다. 몇 가지 빌드에서 공개적으로 사용할 수 있습니다.

다음은 OpenCL에서 Mandelbrot 프랙탈을 계산하는 작은 작업 예입니다. 소프트웨어 구현에 비해 계산 속도가 크게 빨라집니다. OpenCL에서의 계산은 100배 더 빠른 것으로 나타났습니다.

스크립트를 직접 실행하려면 CLContextCreate , CLProgramCreate , CLKernelCreate , CLBufferCreate 등의 함수를 사용하여 라이브러리를 연결해야 합니다. 이 라이브러리는 무엇이며 어디서 구할 수 있습니까?

 
tol64 :

스크립트를 직접 실행하려면 CLContextCreate , CLProgramCreate , CLKernelCreate , CLBufferCreate 등의 함수를 사용하여 라이브러리를 연결해야 합니다. 이 라이브러리는 무엇이며 어디서 구할 수 있습니까?

OpenCL 폴더에서 ... 몇 가지 빌드에서 .. :)
 
tol64 :

스크립트를 직접 실행하려면 CLContextCreate , CLProgramCreate , CLKernelCreate , CLBufferCreate 등의 함수를 사용하여 라이브러리를 연결해야 합니다. 이 라이브러리는 무엇이며 어디서 구할 수 있습니까?

라이브러리가 필요하지 않으며 MQL5의 OpenCL 지원은 이제 기본입니다.

터미널에 추가 DLL 파일이 없습니다. 로드할 때 터미널은 시스템에 OpenCL 인터페이스의 존재를 감지합니다(비디오 카드 드라이버에 의해 추가됨). OpenCL을 제공하는 모든 그래픽 카드 제조업체(NVIDIA, AMD, Intel)가 지원됩니다.

비디오 카드 드라이버는 OpenCL 인터페이스에 대한 지원이 활성화된 최신 상태여야 합니다. 종종 표준 드라이버는 OpenCL을 지원하지 않거나 너무 오래되어 OpenCL/CUDA 라이브러리 구현에 심각한 오류 가 포함된 컴퓨터와 함께 제공됩니다. 이 모든 것은 일반적으로 제조업체 웹 사이트에서 최신 드라이버를 설치하여 처리됩니다.

 
Renat :
Renat, 이제 기사를 작성해야 합니다. 사용법, 기능, 장작을 얻는 위치 등.
 
Renat :

우리는 MQL5에서 직접 OpenCL에 대한 기본 지원을 위해 노력하고 있습니다. 몇 가지 빌드에서 공개적으로 사용할 수 있습니다.

이것은 "비디오" 에이전트가 메타 테스터에 연결될 수 있음을 의미합니까? Opencl은 가능한 경우 모든/대부분의 전문가 또는 비디오 카드 사용을 위해 작성("선명하게")될 전문가에게만 사용됩니까?
 
Renat :

좋은 소식! 고맙습니다.

더엑스퍼트 :
Renat, 이제 기사를 작성해야 합니다. 사용법, 기능, 장작을 얻는 위치 등.

예, 필요할 것입니다.

 
TheXpert :
Renat, 이제 기사를 작성해야 합니다. 사용법, 기능, 장작을 얻는 위치 등.

인터넷에는 이미 OpenCL 에 대한 자료가 많이 있습니다.

여기에서 시작할 수 있습니다.

모든 OpenCL 기능은 MQL5에서 1:1로 사용되므로 다른 기사의 설명을 MQL5로 옮기는 데 문제가 없습니다.

 
joo :

예, 필요할 것입니다.

예, 설명서와 기사 모두에서 OpenCL의 사용 을 설명하려고 노력할 것입니다.
 
WChas :
이것은 "비디오" 에이전트가 메타 테스터에 연결될 수 있음을 의미합니까? Opencl은 가능한 경우 모든/대부분의 전문가 또는 비디오 카드 사용을 위해 작성("선명하게")될 전문가에게만 사용됩니까?

예, 연결할 수 있습니다. 이것이 바로 초점입니다.

에이전트에 OpenCL 장치가 없으면 소프트웨어 구현이 자동으로 작동합니다.

 
내 Radeon 6930이 암호화폐보다 더 수익성이 좋은 경우 제공할 준비가 되었습니다. 하루에 2-3 USD이면 만족할 것입니다. Core i5 i7 프로세서처럼 유휴 상태가 된다면 IMHO는 흥미롭지 않습니다.