Differences

This shows you the differences between two versions of the page.

Link to this comparison view

asc:laboratoare:05 [2026/02/23 18:48]
giorgiana.vlasceanu
asc:laboratoare:05 [2026/04/01 04:23] (current)
alexandru.bala [Warp-uri și modelul SIMT]
Line 1: Line 1:
-====== Laboratorul 05 - Arhitecturi ​de tip GPGPU ======+====== Laboratorul 5 - Arhitecturi GPGPU și Programare CUDA ======
  
 ===== Introducere ===== ===== Introducere =====
Line 86: Line 86:
  
 Dezvoltarea de cod pentru laboratoarele de GPU se va face folosind CUDA. Dezvoltarea de cod pentru laboratoarele de GPU se va face folosind CUDA.
 +
 +
 +{{https://​docs.nvidia.com/​cuda/​cuda-programming-guide/​_images/​gpu-devotes-more-transistors-to-data-processing.png?​800|The GPU Devotes More Transistors to Data Processing}}
 +{{https://​docs.nvidia.com/​cuda/​cuda-programming-guide/​_images/​gpu-cpu-system-diagram.png?​600|A GPU has many streaming multiprocessors (SMs), each of which contains many functional units. Graphics processing clusters (GPCs) are collections of SMs. A GPU is a set of GPCs connected to the GPU memory. A CPU typically has several cores and a memory controller which connects to the system memory. A CPU and a GPU are connected by an interconnect such as PCIe or NVLINK}}
 +{{https://​developer-blogs.nvidia.com/​wp-content/​uploads/​2020/​06/​memory-hierarchy-in-gpus-1.png?​600|Memory hierarchy in GPUs}}
  
 ==== De ce CUDA? ==== ==== De ce CUDA? ====
Line 94: Line 99:
  
 Un standard alternativ la CUDA este **OpenCL**, suportat de Khronos și implementat de majoritatea producătorilor de GPU (inclusiv Nvidia ca o extensie la CUDA). OpenCL suferă de următoarele lipsuri: Un standard alternativ la CUDA este **OpenCL**, suportat de Khronos și implementat de majoritatea producătorilor de GPU (inclusiv Nvidia ca o extensie la CUDA). OpenCL suferă de următoarele lipsuri:
-* suportul este fragmentat +  ​* suportul este fragmentat 
-* standardul este mult mai restrictiv (decât CUDA) +  * standardul este mult mai restrictiv (decât CUDA) 
-* mai complicat de scris programe (decât CUDA)+  * mai complicat de scris programe (decât CUDA)
  
 ===== Arhitectura Nvidia CUDA ===== ===== Arhitectura Nvidia CUDA =====
  
-CUDA (**C**ompute **U**nified **D**evice **A**rchitecture) permite utilizarea limbajului C pentru programarea pe GPU-urile Nvidia cât și extensii pentru alte limbaje (exp. Python). Deoarece una din zonele țintă pentru CUDA este HPC (**H**igh **P**erformance **C**omputing),​ în care limbajul Fortran este foarte popular, PGI ofera un compilator de Fortran ce permite generarea de cod și pentru GPU-urile Nvidia. Există binding-uri pentru Java (jCuda), Python (PyCUDA) și .NET (CUDA.NET).+CUDA (**C**ompute **U**nified **D**evice **A**rchitecture) permite utilizarea limbajului C pentru programarea pe GPU-urile Nvidia cât și extensii pentru alte limbaje (ex. Python). Deoarece una din zonele țintă pentru CUDA este HPC (**H**igh **P**erformance **C**omputing),​ în care limbajul Fortran este foarte popular, PGI ofera un compilator de Fortran ce permite generarea de cod și pentru GPU-urile Nvidia. Există binding-uri pentru Java (jCuda), Python (PyCUDA) și .NET (CUDA.NET).
  
 {{:​asc:​lab7:​cuda-software.png?​800|}} {{:​asc:​lab7:​cuda-software.png?​800|}}
Line 123: Line 128:
 Un kernel se definește folosind specificatorul ''​__global__''​ iar execuția sa se face printr-o configurație de execuție folosind <​nowiki>​ <<<​...>>>​ </​nowiki>​. Configurația de execuție denotă numarul de blocuri și numărul de thread-uri dintr-un block. Fiecare thread astfel poate fi identificat unic prin ''​blockIdx''​ și ''​threadIdx''​. Un kernel se definește folosind specificatorul ''​__global__''​ iar execuția sa se face printr-o configurație de execuție folosind <​nowiki>​ <<<​...>>>​ </​nowiki>​. Configurația de execuție denotă numarul de blocuri și numărul de thread-uri dintr-un block. Fiecare thread astfel poate fi identificat unic prin ''​blockIdx''​ și ''​threadIdx''​.
  
-{{:​asc:​lab7:​cuda-scalability.png?​640|}}+{{https://​docs.nvidia.com/​cuda/​cuda-programming-guide/​_images/​grid-of-thread-blocks.png?​600|Grid of Thread Blocks. Each arrow represents a thread (the number of arrows is not representative of actual number of threads)}} 
 +{{https://​developer-blogs.nvidia.com/​wp-content/​uploads/​2017/​01/​Even-easier-intro-to-CUDA-image.png?​700|Grid,​ Block and Thread indexing in CUDA kernels (one-dimensional)}} 
 +{{:​asc:​lab7:​cuda-scalability.png?​600|}} 
 +{{https://​docs.nvidia.com/​cuda/​cuda-programming-guide/​_images/​thread-block-scheduling.png?​400|When clusters are specified, the thread blocks in a cluster are arranged in their cluster shape within the grid. The thread blocks of a cluster are scheduled simultaneously on the SMs of a single GPC}} 
  
 Mai jos avem definit un kernel, ''​vector_add'',​ care are ca argumente pointeri de tip ''​float'',​ respectiv ''​size_t''​. Acesta calculează $ f(x) = 2x + 1/(x + 1) $, pentru fiecare element din vector. Numărul total de thread-uri este dimensiunea vectorului. Mai jos avem definit un kernel, ''​vector_add'',​ care are ca argumente pointeri de tip ''​float'',​ respectiv ''​size_t''​. Acesta calculează $ f(x) = 2x + 1/(x + 1) $, pentru fiecare element din vector. Numărul total de thread-uri este dimensiunea vectorului.
Line 341: Line 350:
 cudaFree(device_array_b);​ cudaFree(device_array_b);​
 </​code>​ </​code>​
 +
 +===== Warp-uri și modelul SIMT =====
 +
 +În arhitectura CUDA, thread-urile dintr-un bloc sunt organizate în grupuri de cate 32, numite ''​warps''​. Acestea funcționează conform paradigmei SIMT (Single-Instruction Multiple-Threads),​ în care toate firele dintr-un warp execută aceeași instrucțiune simultan, dar pot urma căi de execuție diferite prin cod. Atunci când firele dintr-un warp urmează ramuri diferite ale unui bloc condițional,​ cele care nu se încadrează în ramura activă sunt "​mascate"​ temporar — fenomen cunoscut drept "warp divergence"​. Utilizarea eficientă a GPU-ului este maximizată atunci când toate firele dintr-un warp urmează același flux de control, motiv pentru care numărul total de fire dintr-un bloc ar trebui să fie un multiplu de 32.
 +
 +{{https://​docs.nvidia.com/​cuda/​cuda-programming-guide/​_images/​active-warp-lanes.png?​600|In this example, only threads with even thread index execute the body of the if statement, the others are masked off while the body is executed.
 +}}
 +
 +Deși SIMT este adesea comparat cu SIMD (Single Instruction Multiple Data), există o diferență esențială:​ în SIMD există un singur control flow path, pe când în SIMT fiecare fir poate urma propriul control flow path. Tocmai de asta SIMT nu are un data-width fix, precum la SIMD. Este esențial să ținem cont de warp-uri atunci când scriem cod CUDA, deoarece înțelegerea acestui model ajută la optimizarea accesului la memoria globală, partajată și a altor tehnici avansate. De asemenea, programele care încalcă modelul de programare SIMT pot genera comportament nedefinit, care poate varia în funcție de hardware-ul GPU utilizat.
  
 ===== Aplicații ===== ===== Aplicații =====
Line 384: Line 402:
  
   * Documentatie CUDA:   * Documentatie CUDA:
 +    * [[https://​docs.nvidia.com/​cuda/​cuda-programming-guide/​index.html|CUDA Programming]]
     * [[https://​docs.nvidia.com/​cuda/​cuda-c-programming-guide/​index.html|CUDA C Programming]]     * [[https://​docs.nvidia.com/​cuda/​cuda-c-programming-guide/​index.html|CUDA C Programming]]
     * [[https://​docs.nvidia.com/​cuda/​pdf/​CUDA_Compiler_Driver_NVCC.pdf| CUDA NVCC compiler]]     * [[https://​docs.nvidia.com/​cuda/​pdf/​CUDA_Compiler_Driver_NVCC.pdf| CUDA NVCC compiler]]
asc/laboratoare/05.1771865293.txt.gz · Last modified: 2026/02/23 18:48 by giorgiana.vlasceanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0