Nvidia CUDA
NVIDIA CUDA (Compute Unified Device Architecture) est une plateforme de calcul parallèle et un modèle de programmation développé par NVIDIA. CUDA permet aux développeurs d'utiliser des GPU NVIDIA haute performance (Graphics Processing Units) pour effectuer des tâches de calcul à usage général. Grâce à CUDA, les développeurs peuvent exploiter les puissantes capacités de calcul des GPU pour des calculs parallèles à grande échelle, améliorant considérablement les performances des applications, en particulier dans des domaines tels que le calcul scientifique, l'apprentissage automatique, le traitement d'images et la simulation physique. CUDA prend en charge plusieurs langages de programmation, tels que C, C++ et Python, et fournit un ensemble riche de bibliothèques et d'outils pour aider les développeurs à obtenir facilement le calcul accéléré par GPU.
Bases de la programmation CUDA
Comment pouvons-nous invoquer les ressources GPU dans un programme pour accélérer l'exécution du code? En utilisant CUDA, nous pouvons facilement gérer des milliers de cœurs de calcul au sein du GPU. Le modèle de programmation CUDA est un modèle hétérogène qui nécessite que le CPU et le GPU travaillent ensemble. Dans la programmation CUDA, les termes "host" et "device" sont utilisés pour distinguer les appareils où le code est exécuté.
- Host: CPU et mémoire hôte
- Device: GPU et mémoire vidéo
Généralement, le programme principal se charge sur le CPU, puis copie les données d'initialisation vers le GPU. Le GPU effectue les calculs et copie les résultats vers le CPU.
Nous pouvons utiliser un kernel dans un programme CUDA pour implémenter le processus ci-dessus. Dans CUDA, un kernel fait référence à une fonction qui, lorsqu'elle est appelée, provoque le lancement par le GPU de nombreux threads simultanément pour exécuter ce kernel, réalisant ainsi le parallélisme. Chaque thread exécute le kernel en utilisant son ID de thread pour correspondre à l'index des données d'entrée, garantissant que chaque thread exécute le même kernel mais traite des données différentes.
Le GPU a un grand nombre de cœurs de calcul, et CUDA utilise une structure organisationnelle à deux niveaux pour gérer ces cœurs. Voici trois concepts de programmation CUDA qui doivent être introduits: Thread, Block et Grid.
- Thread: Un programme parallèle CUDA est exécuté par de nombreux threads.
- Block: Plusieurs threads sont regroupés pour former un bloc.
- Grid: Plusieurs blocs sont ensuite organisés en une grille.
Note: Les threads au sein du même bloc peuvent se synchroniser et communiquer via la mémoire partagée.
Dans CUDA, chaque thread a un identifiant unique appelé ThreadIdx, qui change en fonction de la façon dont le Grid et le Block sont divisés.
De plus, voici une brève introduction au modèle de mémoire CUDA, comme illustré dans le diagramme ci-dessous. Chaque thread a sa propre mémoire locale privée, tandis que chaque bloc de threads comprend une mémoire partagée accessible par tous les threads du bloc, avec une durée de vie égale à celle du bloc de threads. De plus, tous les threads peuvent accéder à la mémoire globale. Il existe également des espaces mémoire en lecture seule: mémoire constante et mémoire de texture. La structure mémoire implique l'optimisation du programme, qui ne sera pas discutée en détail ici.
Cas de démonstration CUDA
Maintenant, découvrons l'accélération GPU à travers un exemple simple. Dans cet exemple, nous calculerons la somme de deux vecteurs sur le CPU et le GPU, et comparerons les vitesses de calcul entre CPU et GPU.
Préparation de l'environnement d'exécution
Le système d'exploitation JetPack inclut déjà l'environnement d'exécution CUDA. Nous pouvons vérifier la version de CUDA en utilisant l'outil jtop. Ouvrez le terminal et exécutez jtop.
jtop
Note: Si jtop n'est pas installé sur votre système, veuillez consulter ce guide.
Ci-dessous, nous utiliserons Python pour écrire du code CUDA. Nous devons donc exécuter la commande suivante dans le terminal pour installer Numba.
pip install numbaExécution du code d'exemple
Étape 1: Créez un script Python pour ce cours dans le répertoire racine:
mkdir -p ~/reComputer_J/3.4_CUDA
touch ~/reComputer_J/3.4_CUDA/add_compare.pyÉtape 2: Ouvrez VSCode dans le répertoire où se trouve le script:
cd ~/reComputer_J/3.4_CUDA
code .Étape 3: Dans la barre de navigation de gauche, nous pouvons voir hello_world.py. Entrez le code suivant dans le fichier python:
Cliquez pour développer le code
from numba import cuda, float32
import numpy as np
import time
@cuda.jit
def add_gpu(a, b, out):
tx = cuda.threadIdx.x
ty = cuda.blockIdx.x
block_size = cuda.blockDim.x
grid_size = cuda.gridDim.x
start = tx + ty * block_size
stride = block_size * grid_size
for i in range(start, a.shape[0], stride):
out[i] = a[i] + b[i]
def add_cpu(a, b, out):
for i in range(a.shape[0]):
out[i] = a[i] + b[i]
def main():
# Prepare test data
n = 10000000
a = np.arange(n).astype(np.float32)
b = np.arange(n).astype(np.float32)
out = np.empty_like(a)
# 1. Test CPU computation time
start = time.time()
add_cpu(a, b, out)
print("CPU Time Taken:", time.time()-start)
# 2. Test GPU computation time
# Copy data from host memory to device memory
d_a = cuda.to_device(a)
d_b = cuda.to_device(b)
d_out = cuda.device_array_like(out)
# Define the number of threads per block and the number of blocks
threads_per_block = 256
blocks_per_grid = (n + threads_per_block - 1) // threads_per_block
# Compute the result
start_gpu = time.time()
add_gpu[blocks_per_grid, threads_per_block](d_a, d_b, d_out)
end_gpu = time.time()
# Copy the result from device memory back to host memory
d_out.copy_to_host(out)
print("GPU Time Taken:", end_gpu-start_gpu)
if __name__ == "__main__":
main()
Étape 4: Cliquez sur le bouton d'exécution pour voir le résultat du script Python dans le terminal.

D'après les résultats imprimés dans le terminal, on peut observer que la vitesse de calcul du GPU est plus rapide.
Plus de tutoriels d'apprentissage CUDA
| Tutoriel | Type | Description |
|---|---|---|
| Getting Started with CUDA Programming(zh) | Document | Un tutoriel minimaliste pour commencer avec la programmation CUDA en chinois |
| CUDA C++ Programming Guide | Document | Le guide de programmation pour le modèle et l'interface CUDA. |