CUDA(Compute Unified Device Architecture)是一种由NVIDIA开发的并行计算平台和编程模型,它允许开发者使用NVIDIA的GPU(图形处理单元)进行通用计算。以下是一些基本的CUDA编程概念和步骤,以及一个简单的编程案例。
基本概念:
-
**核函数(Kernel)**:用 `global` 修饰的函数,运行在GPU上。
-
**主机代码和设备代码**:主机代码运行在CPU上,设备代码运行在GPU上。
-
**内存管理**:需要使用 `cudaMalloc` 和 `cudaFree` 管理GPU内存。
-
**数据传输**:使用 `cudaMemcpy` 在主机和设备之间传输数据。
-
**线程和线程块**:线程块是一组线程的集合,线程块组织成网格。
基本步骤:
- **包含CUDA头文件**:
```cpp
#include <cuda_runtime.h>
```
- **定义核函数**:
```cpp
global void add(int *c, int *a, int *b) {
int index = threadIdx.x + blockIdx.x * blockDim.x;
c[index] = a[index] + b[index];
}
```
- **分配GPU内存**:
```cpp
int *dev_a, *dev_b, *dev_c;
size_t size = N * sizeof(int);
cudaMalloc(&dev_a, size);
cudaMalloc(&dev_b, size);
cudaMalloc(&dev_c, size);
```
- **初始化数据**:
```cpp
int *h_a = new int[N];
int *h_b = new int[N];
// Initialize h_a and h_b
```
- **从主机复制数据到设备**:
```cpp
cudaMemcpy(dev_a, h_a, size, cudaMemcpyHostToDevice);
cudaMemcpy(dev_b, h_b, size, cudaMemcpyHostToDevice);
```
- **调用核函数**:
```cpp
add<<<gridSize, blockSize>>>(dev_c, dev_a, dev_b);
```
- **从设备复制结果回主机**:
```cpp
cudaMemcpy(h_c, dev_c, size, cudaMemcpyDeviceToHost);
```
- **释放GPU内存**:
```cpp
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
```
编程案例:
假设我们要编写一个CUDA程序来计算两个向量的和。
**主函数**:
```cpp
int main() {
int N = 256; // 向量大小
size_t size = N * sizeof(int);
int *h_a = new int[N], *h_b = new int[N], *h_c = new int[N];
// 初始化h_a和h_b
int *dev_a, *dev_b, *dev_c;
cudaMalloc(&dev_a, size);
cudaMalloc(&dev_b, size);
cudaMalloc(&dev_c, size);
cudaMemcpy(dev_a, h_a, size, cudaMemcpyHostToDevice);
cudaMemcpy(dev_b, h_b, size, cudaMemcpyHostToDevice);
// 计算网格和线程块大小
int blockSize = 256;
int gridSize = (int)ceil((float)N / blockSize);
// 调用核函数
add<<<gridSize, blockSize>>>(dev_c, dev_a, dev_b);
// 将结果从设备内存复制回主机内存
cudaMemcpy(h_c, dev_c, size, cudaMemcpyDeviceToHost);
// 检查结果
for (int i = 0; i < N; i++) {
assert(h_c[i] == h_a[i] + h_b[i]);
}
// 清理
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
delete[] h_a;
delete[] h_b;
delete[] h_c;
return 0;
}
```
请注意,这个案例是一个简化的示例,用于展示CUDA编程的基本结构。在实际应用中,你可能需要考虑更复杂的错误处理和性能优化。