|
| 1 | +# CUDA 入门 |
| 2 | + |
| 3 | +## config cuda |
| 4 | +export LD_LABRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-11.6/lib64 |
| 5 | +export PATH=$PATH:/usr/local/cuda-11.6/bin |
| 6 | +export CUDA_HOME=$CUDA_HOME:/usr/local/cuda-11.6 |
| 7 | +export PATH=/usr/local/cuda/bin:$PATH |
| 8 | + |
| 9 | + |
| 10 | +## 核函数(Kernel function) |
| 11 | + |
| 12 | +外观: |
| 13 | + |
| 14 | +1. 核函数在GPU上进行并行执行。 |
| 15 | +2. 核函数外观要注意两点: |
| 16 | + - 必须用限定词__global__修饰符。 |
| 17 | + - 核函数返回值必须是void。 |
| 18 | + |
| 19 | +特点: |
| 20 | + |
| 21 | +1. 核函数只能访问GPU内存 |
| 22 | +2. 核函数不能使用变长参数 |
| 23 | +3. 核函数不能使用静态变量 |
| 24 | +4. 核函数不能使用函数指针 |
| 25 | +5. 核函数具有异步性 |
| 26 | + |
| 27 | + |
| 28 | +2. 核函数的输入参数是全局内存中的数据,输出参数是全局内存中的数据。 |
| 29 | +3. 核函数的执行时间由GPU硬件决定,通常是微秒级。 |
| 30 | +4. 核函数的编程语言是CUDA C。 |
| 31 | +5. 核函数的执行效率高于CPU上的函数,因为GPU的并行性可以提高计算效率。 |
| 32 | +6. 核函数的编程难度较低,只需要熟悉CUDA C语言即可。 |
| 33 | + |
| 34 | +## CUDA编程模型 |
| 35 | + |
| 36 | +1. CUDA编程模型是一种并行编程模型,它将程序分解为多个核函数,每个核函数运行在一个线程块上。 |
| 37 | +2. 线程块是一组线程,它们共享同一块全局内存。 |
| 38 | +3. 线程块的大小由硬件决定,通常是128、256、512、1024或2048个线程。 |
| 39 | +4. 线程块的数量由硬件决定,通常是由GPU的核心数决定的。 |
| 40 | +5. 线程块之间可以并行执行,因此可以提高计算效率。 |
| 41 | +6. CUDA编程模型的编程难度较高,需要熟悉CUDA C语言、CUDA运行时库、CUDA编程模型、GPU硬件架构等知识。 |
| 42 | + |
| 43 | +## CUDA编程模型的基本步骤 |
| 44 | + |
| 45 | +1. 编写核函数,在CUDA C语言中定义。 |
| 46 | +2. 编译核函数,将核函数编译成可执行文件。 |
| 47 | +3. 加载核函数,将可执行文件加载到GPU上。 |
| 48 | +4. 创建线程块,在GPU上创建线程块。 |
| 49 | +5. 启动线程块,启动线程块中的线程。 |
| 50 | +6. 等待线程块完成,等待线程块中的线程完成计算。 |
| 51 | +7. 释放资源,释放线程块、全局内存等资源。 |
| 52 | + |
| 53 | +## CUDA编程模型的基本代码示例 |
| 54 | + |
| 55 | +``` |
| 56 | +#include <stdio.h> |
| 57 | +#include <cuda_runtime.h> |
| 58 | +
|
| 59 | +__global__ void add(int *a, int *b, int *c) { |
| 60 | + int i = threadIdx.x; |
| 61 | + c[i] = a[i] + b[i]; |
| 62 | +} |
| 63 | +
|
| 64 | +int main() { |
| 65 | + int a[10], b[10], c[10]; |
| 66 | + int *dev_a, *dev_b, *dev_c; |
| 67 | + size_t size = sizeof(int) * 10; |
| 68 | +
|
| 69 | + // 申请设备内存 |
| 70 | + cudaMalloc((void**)&dev_a, size); |
| 71 | + cudaMalloc((void**)&dev_b, size); |
| 72 | + cudaMalloc((void**)&dev_c, size); |
| 73 | +
|
| 74 | + // 向设备内存中拷贝数据 |
| 75 | + cudaMemcpy(dev_a, a, size, cudaMemcpyHostToDevice); |
| 76 | + cudaMemcpy(dev_b, b, size, cudaMemcpyHostToDevice); |
| 77 | +
|
| 78 | + // 启动核函数 |
| 79 | + add<<<1, 10>>>(dev_a, dev_b, dev_c); |
| 80 | +
|
| 81 | + // 等待核函数完成 |
| 82 | + cudaDeviceSynchronize(); |
| 83 | +
|
| 84 | + // 从设备内存中拷贝数据 |
| 85 | + cudaMemcpy(c, dev_c, size, cudaMemcpyDeviceToHost); |
| 86 | +
|
| 87 | + // 释放设备内存 |
| 88 | + cudaFree(dev_a); |
| 89 | + cudaFree(dev_b); |
| 90 | + cudaFree(dev_c); |
| 91 | +
|
| 92 | + // 输出结果 |
| 93 | + for (int i = 0; i < 10; i++) { |
| 94 | + printf("%d + %d = %d\n", a[i], b[i], c[i]); |
| 95 | + } |
| 96 | +
|
| 97 | + return 0; |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | + |
| 102 | +参考:https://www.bilibili.com/video/BV1sM4y1x7of?spm_id_from=333.788.videopod.episodes&vd_source=665e35db8f931ad6292d3b95f67d4554&p=2 |
| 103 | + |
0 commit comments