CUDA Event:GPU 时间线上的事件、同步原理与实战

CUDA kernel launch 通常是异步的:CPU 把 kernel、内存拷贝等操作提交到 stream 后便继续执行。由此产生两个常见问题:如何准确测量 GPU 工作耗时,以及如何让不同 stream 在不阻塞 CPU 的情况下建立依赖? CUDA Event 就是解决这类问题的基础设施。它可以理解为插入 GPU stream 时间线中的一个标记:当 event 之前的工作全部完成,event 才进入完成状态。借助这个状态,我们可以做 GPU 计时、CPU 等待、跨 stream 同步和异步资源回收。 1. Event 不是 CPU 事件,而是 GPU 时间线标记 一个 CUDA stream 是按序执行的 GPU 工作队列: CPU 提交: Kernel A → memcpy → Event E → Kernel B 异步提交 GPU 执行: Kernel A ── memcpy ── E 完成 ── Kernel B 调用 cudaEventRecord(event, stream) 时,CPU 通常只是向 stream 提交一个 event 记录操作,并不会等待 GPU 执行到该位置。只有当这个 stream 中排在 event 前面的操作完成后,event 才会被标记为完成。 ...

2026年8月31日 · 6 分钟 · Hellokitty

从朴素循环到硬件极限:GEMM / GEMV 高性能算子优化指南

GEMM 与 GEMV 看起来都只是乘加: GEMM: C = alpha * A * B + beta * C GEMV: y = alpha * A * x + beta * y 但二者的最佳实现完全不同。GEMM 可以反复复用矩阵块,通常有机会逼近计算峰值;GEMV 中矩阵元素通常只读一次,往往受内存带宽限制。高性能算子的第一步不是写 SIMD 或 CUDA,而是先判断瓶颈究竟在哪里。 本文给出一条从正确基线走向高性能内核的完整路线。重点不是某段固定代码,而是每一步为什么有效、如何验证,以及何时应该停止优化。 一、先建立性能上限 1. 计算量 对于矩阵尺寸: A: M × K B: K × N C: M × N GEMM 约执行: FLOPs = 2 * M * N * K GEMV 是 N = 1 的特殊形态: FLOPs = 2 * M * K 乘法和加法各算一次浮点操作。 ...

2026年8月26日 · 6 分钟 · Hellokitty