CUDA编程入门教程
CUDA编程入门教程
介绍
欢迎来到CUDA编程的入门教程。在本教程中,我们将学习如何使用NVIDIA的CUDA平台来进行并行计算。CUDA允许我们利用GPU的强大计算能力来加速各种计算密集型任务。
安装CUDA工具包
首先,确保你的计算机上安装了NVIDIA的CUDA工具包。你可以从NVIDIA官方网站下载适合你的操作系统版本的CUDA工具包,并按照官方文档的指导安装。
编写第一个CUDA程序
让我们从一个简单的示例开始,该示例将执行向量相加操作。
步骤1:包含必要的头文件
#include <iostream>
#include <cstdlib>
#include <ctime>
步骤2:定义向量大小
const int N = 100000;
步骤三:主机端(CPU端)代码
void vectorAddCPU(int *a, int *b, int *c, int size) {
for (int i = 0; i < size; ++i) {
c[i] = a[i] + b[i];
}
}
步骤四:设备端(GPU端)代码
__global__ void vectorAddGPU(int *a, int *b, int *c, int size) {
int tid = blockIdx.x * blockDim.x + threadIdx.x;
if (tid < size) {
c[tid] = a[tid] + b[tid];
}
}
步骤五:主函数
int main() {
// 分配主机内存
int *h_a, *h_b, *h_c;
h_a = new int[N];
h_b = new int[N];
h_c = new int[N];
// 初始化向量数据
for (int i = 0; i < N; ++i) {
h_a[i] = rand() % 100;
h_b[i] = rand() % 100;
}
// 分配设备内存
int *d_a, *d_b, *d_c;
cudaMalloc((void**)&d_a, sizeof(int) * N);
cudaMalloc((void**)&d_b, sizeof(int) * N);
cudaMalloc((void**)&d_c, sizeof(int) * N);
// 将数据从主机拷贝到设备
cudaMemcpy(d_a, h_a, sizeof(int) * N, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, h_b, sizeof(int) * N, cudaMemcpyHostToDevice);
// 定义网格和线程块大小
int threadsPerBlock = 256;
int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
// 调用设备端函数
vectorAddGPU<<<blocksPerGrid, threadsPerBlock>>>(d_a, d_b, d_c, N);
// 将结果从设备拷贝回主机
cudaMemcpy(h_c, d_c, sizeof(int) * N, cudaMemcpyDeviceToHost);
// 释放内存
delete[] h_a;
delete[] h_b;
delete[] h_c;
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
return 0;
}
这个示例演示了一个简单的向量相加操作,其中主机端负责分配内存、初始化数据,然后将数据从主机拷贝到设备,调用设备端函数,在设备上执行向量相加操作,最后将结果从设备拷贝回主机。
总结
这个示例演示了一个简单的向量相加操作,其中主机端负责分配内存、初始化数据,然后将数据从主机拷贝到设备,调用设备端函数,在设备上执行向量相加操作,最后将结果从设备拷贝回主机。
全部代码
#include <iostream>
#include <cstdlib>
#include <ctime>
// 定义向量大小
const int N = 100000;
// 主机端(CPU端)向量相加函数
void vectorAddCPU(int *a, int *b, int *c, int size) {
for (int i = 0; i < size; ++i) {
c[i] = a[i] + b[i];
}
}
// 设备端(GPU端)向量相加函数
__global__ void vectorAddGPU(int *a, int *b, int *c, int size) {
int tid = blockIdx.x * blockDim.x + threadIdx.x;
if (tid < size) {
c[tid] = a[tid] + b[tid];
}
}
int main() {
// 分配主机内存
int *h_a, *h_b, *h_c;
h_a = new int[N];
h_b = new int[N];
h_c = new int[N];
// 初始化向量数据
for (int i = 0; i < N; ++i) {
h_a[i] = rand() % 100;
h_b[i] = rand() % 100;
}
// 分配设备内存
int *d_a, *d_b, *d_c;
cudaMalloc((void**)&d_a, sizeof(int) * N);
cudaMalloc((void**)&d_b, sizeof(int) * N);
cudaMalloc((void**)&d_c, sizeof(int) * N);
// 将数据从主机拷贝到设备
cudaMemcpy(d_a, h_a, sizeof(int) * N, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, h_b, sizeof(int) * N, cudaMemcpyHostToDevice);
// 定义网格和线程块大小
int threadsPerBlock = 256;
int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
// 调用设备端函数
vectorAddGPU<<<blocksPerGrid, threadsPerBlock>>>(d_a, d_b, d_c, N);
// 将结果从设备拷贝回主机
cudaMemcpy(h_c, d_c, sizeof(int) * N, cudaMemcpyDeviceToHost);
// 检查结果是否正确
bool success = true;
for (int i = 0; i < N; ++i) {
if (h_c[i] != h_a[i] + h_b[i]) {
success = false;
break;
}
}
if (success) {
std::cout << "向量相加成功!" << std::endl;
} else {
std::cout << "向量相加失败!" << std::endl;
}
// 释放内存
delete[] h_a;
delete[] h_b;
delete[] h_c;
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
return 0;
}