OpenCL: gerçek problemler - sayfa 5

 
SD'de bir uygulama oluşturun ve kodu ekleyin (PM aracılığıyla yapabilirsiniz), kodunuzu analiz edeceğim.
Общайтесь с разработчиками через Сервисдеск!
Общайтесь с разработчиками через Сервисдеск!
  • www.mql5.com
Ваше сообщение сразу станет доступно нашим отделам тестирования, технической поддержки и разработчикам торговой платформы.
 

Kodumun hangi kısmı özellikle ilgimi çekiyor? Farklı dosyalara çok fazla bağımlılığım var.

Şu anda sahip olduğum sorun, yalnızca test cihazının 1 işareti için arabelleği yazıp okumak ve kontrol etmek için yeterli:

 #property copyright ""
#property link        ""

int hcontext, hprogram, hkernel, hbuffer[ 5 ];

void InitGlobal()
{
   for ( int cdev = ( int ) CLGetInfoInteger ( 0 , CL_DEVICE_COUNT )- 1 ; cdev>- 1 ; cdev--)
   {
       string name;
       CLGetInfoString (cdev, CL_DEVICE_NAME , name);
       Print ( "Device #" ,cdev, " = " ,name);
   }
   
   string source =
"kernel void tester(global double *price, global double *result)                                   \r\n"
"{                                                                                                 \r\n"
"   int global_index = get_global_id(0);                                                           \r\n"
"   result[global_index] = price[global_index] / global_index;                                     \r\n"
"}                                                                                                 \r\n"
;
   
   hcontext = CLContextCreate ( CL_USE_GPU_ONLY );
   string build_log;
   hprogram = CLProgramCreate (hcontext, source, build_log);
   Print ( "build log = " , build_log);
   hkernel = CLKernelCreate (hprogram, "tester" );
}

void DeinitGlobal()
{
   CLBufferFree (hbuffer[ 0 ]);
   CLBufferFree (hbuffer[ 1 ]);
   
   CLKernelFree (hkernel);
   CLProgramFree (hprogram);
   CLContextFree (hcontext);
}

int OnInit ()
{
   InitGlobal();
   return ( 0 );
}

void OnDeinit ( const int reason)
{
   DeinitGlobal();
}

// Скрипт, в отличии от эксперта, можно дебажить на выходных :)
//void OnStart() {  InitGlobal();
void OnTick () {
   double price[ 30 ];
   CopyClose ( _Symbol , _Period , 0 , ArraySize (price),price);
   
   static bool firststart = true ;
   if (firststart)
   {
      firststart = false ;
       uint bufsize = sizeof (price);
       Print ( "Размер буфера в байтах =" ,bufsize);
      hbuffer[ 0 ] = CLBufferCreate (hcontext, bufsize, CL_MEM_READ_ONLY );
      hbuffer[ 1 ] = CLBufferCreate (hcontext, bufsize, CL_MEM_WRITE_ONLY );
      
       CLSetKernelArgMem (hkernel, 0 , hbuffer[ 0 ]);
       CLSetKernelArgMem (hkernel, 1 , hbuffer[ 1 ]);
   }
   
   // А вот здесь не хватает clGetMemObjectInfo(buffer, CL_MEM_SIZE) для проверки размера.
   
   CLBufferWrite (hbuffer[ 0 ], price);
   
   uint units = ( uint ) CLGetInfoInteger (hcontext, CL_DEVICE_MAX_COMPUTE_UNITS );
   uint global_work_offset[] = { 0 };
   uint global_work_size[ 1 ];
   uint local_work_size[ 1 ];
   global_work_size[ 0 ] = ArraySize (price);
   local_work_size[ 0 ] = global_work_size[ 0 ] / units;
   bool exec = CLExecute (hkernel, 1 , global_work_offset, global_work_size, local_work_size); // async
   if (exec == false ) Print ( "Error in " , __FUNCSIG__ , " CLExecute: " , GetLastError ());
   
   CLBufferRead (hbuffer[ 1 ], price);
   
   if ( MQL5InfoInteger ( MQL5_PROGRAM_TYPE ) == PROGRAM_SCRIPT ) DeinitGlobal();
}

Komut dosyası başlatma:

2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) Cihaz #1 = AMD Phenom(tm) II X4 925 İşlemci
2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) Cihaz #0 = Selvi
2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) OpenCL: GPU cihazı 'Cypress' seçildi
2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) derleme günlüğü =
2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) Bayt cinsinden arabellek boyutu =240

2013.01.09'dan 2013.10.10'a kadar "OHLC on M1" ile M5'te test cihazında bir uzman tarafından başlatın:

2013.10.30 19:01:44 Core 1 EURUSD,M5: Experts\OpenCL_buffer_test.ex5'in 2013.01.09 00:00 ile 2013.10.10 00:00 arasında testi başladı
2013.10.30 19:01:44 Çekirdek 1 2013.01.09 00:00:00 Cihaz #0 = Selvi
2013.10.30 19:01:44 Core 1 2013.01.09 00:00:00 OpenCL: GPU cihazı 'Cypress' seçildi
2013.10.30 19:01:44 Çekirdek 1 2013.01.09 00:00:00 derleme günlüğü =
2013.10.30 19:01:44 Çekirdek 1 2013.01.09 00:00:00 Bayt cinsinden arabellek boyutu =240
2013.10.30 19:04:55 Çekirdek 1 EURUSD,M5: 192443 ms içinde oluşturulan 1108637 tik (55953 bar) (geçmişteki toplam çubuklar 131439, toplam süre 192521 ms)
2013.10.30 19:04:55 Çekirdek 1 294 Mb bellek kullanıldı

Lütfen test cihazında yalnızca 1 cihaz olduğunu unutmayın.

Eğer bir

   //CLBufferRead(hbuffer[1], price);

o zamanlar

2013.10.30 19:16:00 Çekirdek 1 EURUSD,M5: 88218 ms içinde oluşturulan 1108637 kene (55953 çubuk) (geçmişteki toplam çubuk sayısı 131439, toplam süre 88297 ms)
 
Okumaya kesinlikle ihtiyaç vardır, aslında çekirdeğin tamamlanmasını bekleme işlevi budur, çünkü CLExecute görevi yalnızca yürütme için kuyruğa alır, ardından tamamlanmasını beklemeden kontrolü MQL programına döndürür
 
Bu özel örnekte, OpenCL kullanmanın yararı, arabellek kopyalama ek yükü tarafından tüketilir.

OHLC verileri üzerinde hesaplama yapmak gerekiyorsa, ekonomik bir kayıt yapmak gerekir, yani. önceden daha büyük bir arabellek oluşturun ve yeni veriler geldiğinde, yeni başlangıç ve arabelleğin boyutu hakkında çekirdeği bilgilendirerek yalnızca bu yeni verileri ekleyin.
OpenCL: Мост в параллельные миры
OpenCL: Мост в параллельные миры
  • 2012.05.16
  • Sceptic Philozoff
  • www.mql5.com
В конце января 2012 года компания-разработчик терминала MetaTrader 5 анонсировала нативную поддержку OpenCL в MQL5. В статье на конкретном примере изложены основы программирования на OpenCL в среде MQL5 и приведены несколько примеров "наивной" оптимизации программы по быстродействию.
 

OHLC aktarımını optimize etmeyi başarsak bile (son çubuğu CLSetKernelArg aracılığıyla aktaracağız), sonuç arabelleğini okurken yine de çöküyoruz:

2013.10.31 19:24:13 Çekirdek 1 EURUSD,M5: 114489 ms içinde oluşturulan 1108637 tik (55953 çubuk) (geçmişteki toplam çubuk sayısı 131439, toplam süre 114598 ms)
(CLBufferWrite(hbuffer[0], fiyat ile satır); EĞER altına taşındı)
 
Roffild : Eh... GPU'da OpenCL ile hızın artırılmasıyla ilgili makaleler bir peri masalı oldu, çünkü gerçek görevleri tanımlamıyorlar :(

Peki, seni kim durduruyor. Gerçek bir şey alın ve yazın ki bir peri masalı olmasın. Ama yine de ivmenin olması için bir örnek bulmaya çalışın. Bu en zor kısım.

Yazılarımdan bahsediyorsak... Neyse, eğitim programı yazdım. Ve matris çarpımı oldukça faydalı bir işlemdir.

Not Bu arada, CPU Intel ise, x86 çekirdeğindeki öykünme, rakibin CPU'sundan çok daha hızlıdır. Bu, eğer çekirdek açısından.

HD5850: Prensipte oldukça iyi bir kart, ancak modern kartlar daha iyi - sadece daha fazla sinek nedeniyle değil, aynı zamanda OpenCL için yapılan optimizasyonlar nedeniyle. Örneğin, genel bellek erişim süresi önemli ölçüde azaltılmıştır.

PPS OpenCL her derde deva değil, bazı nadir durumlarda önemli ölçüde hızlanmasına izin veren gerçek bir araçtır. Ve diğer durumlarda, çok uygun değil, hızlanma o kadar etkileyici değil - eğer varsa.

 
Roffild :
Eh... GPU'da OpenCL ile hızı artırmayla ilgili makaleler bir peri masalı oldu, çünkü gerçek görevleri tanımlamıyorlar :(

Bu taraftan değil. Masal - "herhangi bir algoritma OpenCL'de hızlandırılabilir". Hiç.

OpenCL'deki ilk dal, okl hızlandırma potansiyeline sahip olmak için bir algoritmanın sahip olması gereken kriterleri bile tam olarak tanımlar.

İyi şanlar.

 

İddialar hesaplama hızı ile ilgili değildir - burada hızlanma 2 katıdır (0,02 ms vs 0,05 ms)

Yazılarda herhangi bir bilgi bulunmadığı iddiası:

  • Küçük bir arabellek bile okuma / yazma gecikmesi = 0.35300 ms - çoğu algoritmayı OpenCL'ye dönüştürmeyi anlamsız kılan şey budur!
  • Test cihazı OpenCL için CPU seçmez - bu hiçbir yerde rapor edilmez!

Sözleri okuduktan sonra muhtemelen GPU ile testi hızlandırmak isteyen ilk kişi benim...

MetaDriver : ilk dal, bir algoritmanın tıkanıklık hızlandırma potansiyeline sahip olması için sahip olması gereken kriterleri bile tam olarak tanımlar.

Yazılarımı tekrar oku.

Ana kriter: MQL kodunun 1 onay işareti için "OpenCL stilinde" yürütülmesi, süreyi aşmalıdır = Number_of_Buffers * 0.35300 ms

MQL'deki algoritmanın hızını mikrosaniyelik bir doğrulukla (1000 mikrosaniye = 1 milisaniye) bulmak için test cihazında ve Total_Time / Number_Ticks'te (en üstteki mesajım) birkaç kez çalıştırmanız gerekecek.

Arabellek gecikmesi olmasaydı, kodum testi ~30 saniyede geçti - bu, "OpenCL stili" MQL'den (55 saniye) ~2 kat ve normal koddan (320 saniye) ~11 kat daha hızlıdır.

Diğer kriterler nelerdir?

 
Roffild : hiçbir bilgi bulunmadığı iddiası:
  • Küçük bir arabellek bile okuma / yazma gecikmesi = 0.35300 ms - çoğu algoritmayı OpenCL'ye dönüştürmeyi anlamsız kılan şey budur!

OpenCL ile iletişiminizin deneyimine bakılırsa, her algoritmanın aptalca doğrudan hızlandırılmadığını zaten anlamanız gerekirdi. Burada temel sorunlardan biri, küresel belleğe erişimlerin en aza indirilmesidir.

Bu arada, şimdi benzer bir sorunu cihazın genel belleğine rastgele erişimle çözmem gerekiyor (bu rastgele erişim çok sık ve bu lanet olası bir ek yük). Moskova'yı açar açmaz kesinlikle karar vereceğim.

Test cihazı OpenCL için CPU seçmez - bu hiçbir yerde rapor edilmez!

Servis masasına yazın ve böyle bir özelliğe olan ihtiyacı gerekçelendirin.

Test cihazı kullanılmıyorsa, zaten yapılmıştır (bu benim uygulamam). Henüz bir test cihazında test etmedim.



 
Mathemat :

Zaten her algoritmanın aptalca doğrudan hızlandırılmadığını yazdınız. Burada mosk'u dahil etmek gerekiyor ve ana sorunlardan biri de global belleğe erişimi en aza indirgemek.

Pekala, cho, şimdi cihazın global belleğine rastgele erişimle benzer bir sorunu çözmem gerekiyor (bu rastgele erişim çok sık). Moskova'yı açar açmaz kesinlikle karar vereceğim.

Beyni açmanızın zamanı geldi, çünkü 0.35300 ms özellikle clEnqueue[Read/Write]Buffer ()'ı ifade eder ve çekirdeğin içindeki global bellek erişimini değil.

İkincisi, çekirdeğin kendisini optimize ederek çözülür, ancak birincisi bir demir sınırlamasıdır ve beyin burada yardımcı olmayacaktır.

OpenCL: From Naive Towards More Insightful Programming
OpenCL: From Naive Towards More Insightful Programming
  • 2012.06.29
  • Sceptic Philozoff
  • www.mql5.com
This article focuses on some optimization capabilities that open up when at least some consideration is given to the underlying hardware on which the OpenCL kernel is executed. The figures obtained are far from being ceiling values but even they suggest that having the existing resources available here and now (OpenCL API as implemented by the developers of the terminal does not allow to control some parameters important for optimization - particularly, the work group size), the performance gain over the host program execution is very substantial.