CUDA stream
时间: 2025-05-13 12:47:59 浏览: 34
### CUDA 流的概念
CUDA 流(Stream)是一种用于管理 GPU 上操作顺序和并发性的机制。通过使用多个流,开发者可以在不同流之间实现任务的重叠执行,从而提高硬件利用率和程序性能。
#### 基本概念
- **默认流**:每个 CUDA 上下文中都有一个默认流(Default Stream),它负责串行化所有提交给它的操作。如果未显式指定流,则这些操作会进入默认流[^1]。
- **异步行为**:除了默认流外,其他流都具有异步特性,这意味着当某个流中的操作被发起后,CPU 可以立即继续处理后续的任务而无需等待该操作完成。
#### 创建与销毁流
可以通过 `cudaStreamCreate` 函数创建一个新的流实例,并用 `cudaStreamDestroy` 销毁不再使用的流资源:
```c++
cudaStream_t stream;
cudaStreamCreate(&stream);
// 使用流...
cudaStreamDestroy(stream);
```
#### 数据传输与核函数调用
在实际应用中,通常需要将主机内存的数据复制到设备端或者反过来;同时也可能涉及多次调用同一个或不同的 kernel 来完成复杂的计算逻辑。借助于自定义流,我们可以让上述过程更加高效地并行起来。例如下面的例子展示了如何利用两个独立的 streams 同时上传数据至GPU 并运行各自的 kernels:
```cpp
float *d_A, *d_B; // Device pointers
float *h_A, *h_B; // Host buffers filled with data...
cudaMalloc((void**)&d_A, size); cudaMalloc((void**)&d_B, size);
// Create two separate streams.
cudaStream_t s1,s2;
cudaStreamCreate(&s1);
cudaStreamCreate(&s2);
// Asynchronously copy A to device on first stream
cudaMemcpyAsync(d_A,h_A,size,cudaMemcpyHostToDevice,s1);
myKernel<<<blocksPerGridA,threadsPerBlockA,0,s1>>>(...parameters...)
// Similarly do async operations related B but now using second stream 's2'
cudaMemcpyAsync(d_B,h_B,size,cudaMemcpyHostToDevice,s2);
anotherKernel<<<blocksPerGridB,threadsPerBlockB,0,s2>>>(...params...)
// Cleanup resources after all work done ...
cudaFree(d_A); cudaFree(d_B);
cudaStreamDestroy(s1); cudaStreamDestroy(s2);
```
这里需要注意的是,尽管来自不同streams 的指令可能会交错被执行,但是属于同一stream内的各项命令仍然保持其相对次序不变——即先发出的操作总是会在之后启动的那个之前结束。
#### 同步控制
为了协调多条流之间的相互作用关系,有时还需要引入额外的同步手段。这可通过事件(event)对象来达成目的。简单来说就是记录特定时刻的状态以便稍后再查询确认是否达到预期进展程度。
```c++
cudaEvent_t event;
cudaEventCreate(&event);
someOperation<<<numBlocks,numThreads,sharedMemSize,customStream>>>();
cudaEventRecord(event, customStream);
// Do other stuff here possibly involving different streams etc.
// Later somewhere else where synchronization needed before proceeding further..
cudaEventSynchronize(event);
cudaEventDestroy(event);
```
以上介绍了关于CUDA Streams的一些基础知识及其典型应用场景下的编码实践方法论等内容[^2]。
阅读全文