close

OpenCL

Przejdź do nawigacji Przejdź do wyszukiwania
OpenCL
Heterogeniczna część obliczeniowa
Logo OpenCL.svg
Instalacje programowe OpenCL Mandelbulber v2.23 20201208.png
Informacje ogólne
typ programu Interfejs programowania aplikacji , GPGPU
Autor Manzana
deweloper Grupa Kronos
Pierwsze wydanie 28 sierpnia 2009
Licencja darmowe
Specyfikacja
Zaplanowano w
Obsługiwane platformy
Wersje
Najnowsza stabilna wersja 3.0 [ 1 ]​ ( info ) ( 27 kwietnia 2020 (2 lata, 5 miesięcy i 21 dni) [ 1 ] ​)
Spinki do mankietów

OpenCL ( Open Computing Language ) składa się z interfejsu programowania aplikacji i języka programowania . Razem umożliwiają one tworzenie aplikacji z równoległością na poziomie danych i zadań, które mogą działać zarówno na jednostkach centralnych , jak i procesorach graficznych . Język bazuje na C99 , usuwając część funkcjonalności i rozszerzając go o operacje wektorowe. [ 2 ]

Oryginalna specyfikacja została stworzona przez Apple i opracowana we współpracy z AMD , IBM , Intel i NVIDIA . Apple zaproponował to grupie Khronos , aby stał się otwartym standardem bez opłat licencyjnych. 16 czerwca 2008 r. Khronos utworzył Grupę Roboczą ds . Obliczeń [ 3 ] w celu przeprowadzenia procesu standaryzacji. W 2013 roku została opublikowana wersja 2.0 standardu.

OpenCL jest częścią systemu Mac OS X v10.6 („Snow Leopard”) [ 4 ] , podczas gdy AMD zdecydowało się wspierać OpenCL zamiast starego API Close to Metal . [ 5 ] ​[ 6 ]​ Intel ma również własne środowisko programistyczne, a NVIDIA, oprócz własnego interfejsu API dla układów graficznych o nazwie CUDA, obsługuje również OpenCL.

Przykład

W tym przykładzie obliczana jest szybka transformata Fouriera . [ 2 ]​ Wywołania API są następujące:


// utwórz kontekst obliczeniowy za pomocą kontekstu urządzenia GPU = clCreateContextFromType ( CL_DEVICE_TYPE_GPU );  

// utwórz 
kolejkę roboczą = clCreateWorkQueue ( context , NULL , NULL , 0 );     

// przydziel obiekty pamięci buforowej 
memobjs [ 0 ] = clCreateBuffer ( kontekst , CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR , sizeof ( float ) * 2 * num_entries , srcA );       
memobjs [ 1 ] = clCreateBuffer ( kontekst , CL_MEM_READ_WRITE , sizeof ( float ) * 2 * num_entries , NULL );     

// utwórz program obliczeniowy 
= clCreateProgramFromSource ( context , 1 , & fft1D_1024_kernel_src , NULL ) ;     

// zbuduj plik wykonywalny programu obliczeniowego 
clBuildProgramExecutable ( program , false , NULL , NULL );   

// utwórz jądro obliczeniowe 
= clCreateKernel ( program , fft1D_1024 ) ;   

// utwórz obiekt zakresu ND z wymiarami elementu 
roboczego global_work_size [ 0 ] = n ;  
local_work_size [ 0 ] = 64 ;  
range = clCreateNDRangeContainer ( kontekst , 0 , 1 , global_work_size , local_work_size );      

// ustaw wartości argumentów 
clSetKernelArg ( kernel , 0 , ( void * ) & memobjs [ 0 ] , sizeof ( cl_mem ), NULL );     
clSetKernelArg ( kernel , 1 , ( void * ) & memobjs [ 1 ] , sizeof ( cl_mem ), NULL );     
clSetKernelArg ( jądro , 2 , NULL , sizeof ( float ) * ( local_work_size [ 0 ] +1 ) * 16 , NULL ) ;    
clSetKernelArg ( jądro , 3 , NULL , sizeof ( float ) * ( local_work_size [ 0 ] +1 ) * 16 , NULL ) ;    

 // wykonaj jądro 
clExecuteKernel ( kolejka , jądro , NULL , zakres , NULL , 0 , NULL );      

Samo obliczenie jest następujące:

// To jądro oblicza FFT o długości 1024. Długość FFT o długości 1024 jest 
// rozkładana na wywołania funkcji radix 16, innej funkcji radix 16, a następnie funkcji radix 4 
__kernel void fft1D_1024 ( __global float2 * in , __global float2 * out , __local float * sMemx , __local float * sMemy ) { int tid = get_local_id ( 0 ); int blockIdx = get_group_id ( 0 ) * 1024 + tid ; dane float2 [ 16 ]; // początkowy indeks danych do/z pamięci globalnej in = in + blockIdx ; out = out + blockIdx ; globalLoads ( dane , w , 64 ); // połączone globalne odczyty fftRadix16Pass ( data ); // w miejscu radix-16 pass twiddleFactorMul ( data , tid , 1024 , 0 ); // losowanie lokalne przy użyciu pamięci lokalnej localShuffle ( data , sMemx , sMemy , tid , ((( tid & 15 ) * 65 ) + ( tid >> 4 ))); fftRadix16Pass ( dane ); // w miejscu radix-16 pass twiddleFactorMul ( data , tid , 64 , 4 ); // mnożenie współczynnika twiddle localShuffle ( data , sMemx , sMemy , tid , ((( tid >> 4 ) * 64 ) + ( tid & 15 ))); // cztery wywołania funkcji radix-4 fftRadix4Pass ( data ); fftRadix4Pass ( dane + 4 ); fftRadix4Pass ( dane + 8 ); fftRadix4Pass ( dane + 12 ); // połączone globalne zapisy globalStores ( data , out , 64 ); }         
                                 
      
          
    
  
             
     
        
      
  
               
                 
      
               
  
      
        
  
     

Zobacz także

Referencje

  1. a b Khronos wydaje OpenCL 3.0
  2. ^ a b "OpenCL" . SIGGRAPH2008. 14 sierpnia 2008. Zarchiwizowane z oryginału w dniu 19 marca 2012 . Źródło 14 sierpnia 2008 . 
  3. ^ „Khronos wprowadza inicjatywę heterogenicznego przetwarzania” . Grupa Chronosa. 16 czerwca 2008 r. Zarchiwizowane z oryginału 20 czerwca 2008 r . . Źródło 18 czerwca 2008 . 
  4. „Apple prezentuje system Mac OS X Snow Leopard dla programistów” . Manzana. 9 czerwca 2008 r. Zarchiwizowane od oryginału 11 czerwca 2008 r . . Źródło 9 czerwca 2008 . 
  5. ^ „AMD Drives przyjęcie standardów branżowych w rozwoju oprogramowania GPGPU” . AMD. 6 sierpnia 2008 r. Zarchiwizowane z oryginału 16 września 2008 r . . Źródło 14 sierpnia 2008 . 
  6. ^ „AMD wspiera OpenCL, Microsoft DirectX 11” . eTydzień. 6 sierpnia 2008 r. Zarchiwizowane z oryginału 19 marca 2012 r . . Źródło 14 sierpnia 2008 . 

Linki zewnętrzne