Skip to content

Commit 12cd78d

Browse files
author
vimpas
committed
feat: ✨ Update tag-data.json order and add CUDA programming basics blog post
1 parent 9f7235f commit 12cd78d

File tree

2 files changed

+163
-1
lines changed

2 files changed

+163
-1
lines changed

app/tag-data.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"rag":4,"信息检索":1,"bm25":1,"python":2,"dp":1,"celery":1,"signal":1,"异步任务":1,"事件驱动":1,"ssh":1,"vim":1,"剪切板同步":1,"远程服务器":1,"neovim":1,"next-js":1,"react":1,"javascript":1,"web开发":1}
1+
{"celery":1,"signal":1,"异步任务":1,"事件驱动":1,"next-js":1,"react":1,"javascript":1,"web开发":1,"ssh":1,"vim":1,"剪切板同步":1,"远程服务器":1,"neovim":1,"dp":1,"python":2,"rag":4,"信息检索":1,"bm25":1}
+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
title: 'cuda编程基础'
3+
date: '2024-11-02'
4+
tags: []
5+
draft: false
6+
summary:
7+
---
8+
9+
10+
## CUDA编程基础
11+
12+
CUDA(Compute Unified Device Architecture)是由NVIDIA开发的一种并行计算平台和编程模型,旨在利用GPU的强大计算能力。通过CUDA,开发者能够在GPU上执行计算密集型的任务,从而显著提高程序的性能。以下是CUDA编程的基本概念和步骤。
13+
14+
****CUDA编程模型概述****
15+
16+
在CUDA编程中,CPU被称为*host*,而GPU被称为*device*。这两者有各自独立的内存空间。CUDA程序通常包括以下几个步骤:
17+
18+
- **内存分配**:在host和device上分别分配内存。
19+
20+
- **数据初始化**:在host上初始化数据。
21+
22+
- **数据传输**:将数据从host传输到device。
23+
24+
- **核函数执行**:在device上执行核函数(kernel)。
25+
26+
- **结果传回**:将计算结果从device传回host。
27+
28+
- **内存释放**:释放在host和device上分配的内存。
29+
30+
****CUDA核函数****
31+
32+
核函数是指在GPU上并行执行的函数。使用`__global__`关键字来定义核函数,并通过`<<<grid, block>>>`语法来指定执行配置,其中`grid`表示网格的数量,`block`表示每个网格中的线程块数量。例如:
33+
34+
```cpp
35+
__global__ void vectorAdd(float *A, float *B, float *C, int N) {
36+
int i = blockIdx.x * blockDim.x + threadIdx.x;
37+
if (i < N) {
38+
C[i] = A[i] + B[i];
39+
}
40+
}
41+
```
42+
43+
在这个例子中,`vectorAdd`是一个核函数,它将两个向量相加并将结果存储到第三个向量中。
44+
45+
****线程和块的概念****
46+
47+
CUDA中的线程是执行计算的基本单位。每个线程都有一个唯一的ID,可以通过内置变量如`threadIdx`、`blockIdx`和`blockDim`来访问。线程被组织成块(block),多个块组成一个网格(grid)。这种层次结构使得CUDA能够高效地管理大量并行任务。
48+
49+
****内存管理****
50+
51+
CUDA提供了多种内存类型,包括:
52+
53+
- **全局内存(Global Memory)**:所有线程都可以访问,但访问速度较慢。
54+
55+
- **共享内存(Shared Memory)**:同一块中的线程可以共享,速度较快,但容量有限。
56+
57+
- **局部内存(Local Memory)**:每个线程私有,通常用于存储局部变量。
58+
59+
使用以下API进行内存管理:
60+
61+
- `cudaMalloc()`:在device上分配内存。
62+
63+
- `cudaMemcpy()`:在host和device之间传输数据。
64+
65+
- `cudaFree()`:释放已分配的设备内存。
66+
67+
例如:
68+
69+
```cpp
70+
float *d_A, *d_B, *d_C;
71+
cudaMalloc(&d_A, N * sizeof(float));
72+
cudaMalloc(&d_B, N * sizeof(float));
73+
cudaMalloc(&d_C, N * sizeof(float));
74+
```
75+
76+
****简单示例:向量加法****
77+
78+
以下是一个完整的向量加法示例,包括主机代码和设备代码:
79+
80+
```cpp
81+
#include <stdio.h>
82+
83+
__global__ void vectorAdd(float *A, float *B, float *C, int N) {
84+
int i = blockIdx.x * blockDim.x + threadIdx.x;
85+
if (i < N) {
86+
C[i] = A[i] + B[i];
87+
}
88+
}
89+
90+
int main() {
91+
int N = 1 << 20; // 1M elements
92+
size_t size = N * sizeof(float);
93+
94+
// 在主机上分配内存
95+
float *h_A = (float *)malloc(size);
96+
float *h_B = (float *)malloc(size);
97+
float *h_C = (float *)malloc(size);
98+
99+
// 初始化向量
100+
for (int i = 0; i < N; i++) {
101+
h_A[i] = i;
102+
h_B[i] = i;
103+
}
104+
105+
if (h_A == NULL || h_B == NULL || h_C == NULL) {
106+
printf("Memory allocation failed\n");
107+
return 1;
108+
}
109+
110+
functio
111+
// 在设备上分配内存
112+
float *d_A, *d_B, *d_C;
113+
cudaMalloc(&d_A, size);
114+
cudaMalloc(&d_B, size);
115+
cudaMalloc(&d_C, size);
116+
117+
// 将数据从主机复制到设备
118+
cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
119+
cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
120+
121+
// 启动核函数
122+
int threadsPerBlock = 256;
123+
int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
124+
vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, N);
125+
126+
// 将结果从设备复制回主机
127+
cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
128+
129+
// 验证结果
130+
for (int i = 0; i < N; i++) {
131+
if (h_C[i] != h_A[i] + h_B[i]) {
132+
printf("Error: %f != %f\n", h_C[i], h_A[i] + h_B[i]);
133+
break;
134+
}
135+
}
136+
137+
// 释放设备和主机内存
138+
cudaFree(d_A);
139+
cudaFree(d_B);
140+
cudaFree(d_C);
141+
free(h_A);
142+
free(h_B);
143+
free(h_C);
144+
145+
return 0;
146+
}
147+
```
148+
149+
这个示例展示了如何使用CUDA进行简单的向量加法,包括内存管理、核函数定义及调用等基本操作。
150+
151+
通过以上内容,你可以对CUDA编程有一个初步的了解,并能够编写简单的CUDA程序。随着对CUDA更深入的学习,你将能够掌握更多优化技巧和高级特性,以充分利用GPU的计算能力。
152+
153+
Citations:
154+
[1] https://www.youtube.com/watch?v=IuxJO0HOcH0
155+
[2] https://blog.csdn.net/weixin_44966641/article/details/124448102
156+
[3] https://godweiyang.com/2021/01/25/cuda-reading/
157+
[4] https://developer.nvidia.com/blog/easy-introduction-cuda-c-and-c/
158+
[5] https://blog.csdn.net/m0_37870649/article/details/132122059
159+
[6] https://hpcwiki.io/gpu/cuda/
160+
[7] https://cuda-tutorial.readthedocs.io/en/latest/tutorials/tutorial01/
161+
[8] https://developer.nvidia.com/zh-cn/blog/cuda-model-intro-cn/
162+
[9] https://cuda-tutorial.github.io/part1_22.pdf

0 commit comments

Comments
 (0)