CUDA编程

发布时间:2026/9/18 11:32:01

CUDA编程 一、cuda/gpu线程模型1、cuda线程模型核函数调用方法如下xxx_xxx_xxxgrid_size,block_size(函数参数);以上核函数调用会在gpu中创建grid_size * block_size个线程并行执行核函数内容一维时grid_size为一维时最大值block_size最大值1024三维时grid_size.x/grid_size.y/grid_size.z最大值/65535/65535block_size.x/block_size.y/block_size.z最大值1024/1024/64且block_size.x*block_size.y*block_size.z不能大于1024。2、GPU线程模型3、cuda线程模型与GPU线程模型对应关系二、cuda/gpu内存模型1、PageableMemoryHOST分页内存位于HOST DDR1、主机使用malloc()/free()2、主机使用GPU不能使用3、在stream中如果使用了异步数据传输不能使用该类型的Memory。2、PinnedMemory固定内存位于HOST DDR1、使用cudaMallocHost()/cudaHostAlloc()/cudaFreeHost()2、GPU可通过DMA访问的Host Memory3、在stream中如果使用了异步数据传输需要使用该类型的Memory。3、GlobalMemory全局内存位于GPU DDR1、全局内存cudaMallc()/cudaFree()2、静态全局内存变量核函数外__device__3、常量内存核函数外__constant__4、纹理内存/表面内存5、局部内存在核函数内定义的不加任何修定符的变量在寄存器内存装不下时。6、全局内存的合并传输4、SharedMemory共享内存位于GPU SM SRAM1、类似于寄存器内存区别是整个线程块可见2、静态共享内存使用__shared__修饰声明时需要指定大小3、动态共享内存使用extern __shared__修饰声明时不能指定大小在调用核函数时指定每个线程使用的共享内存大小xxx_xxx_xxxgrid_size, block_size,SharedMemorySize(函数参数);4、共享内存因为更靠近计算单元所以访问速度更快5、共享内存通常可以作为访问全局内存的缓存使用6、可以利用共享内存实现线程间的通信7、通常与__syncthreads同时出现这个函数是同步block内的所有线程全部执行到这一行才往下走8、使用方式通常是在线程id为0的时候从global memory取值然后syncthreads然后再使用。9、共享内存bank冲突问题5、RegisterMemory寄存器内存位于GPU SM1、在核函数内定义的不加任何修定符的变量。三、cuda runtime api以cuda为前缀CUDA Runtime API四、cuda driver api以cu为前缀CUDA Driver API五、原子函数atomicAdd、atomicSub、atomicExch、atomicCAS、atomicInc、atomicDec、atomicMax、atomicMin、atomicAnd、atomicOr、atomicXor六、线程束SM按照线程束包括32个线程进行运算一个线程块只能调度到一个SM如一个线程块有128个线程那就是4个线程束这时会被调度到一个SM上这个SM多度执行这4个线程束一个SM最多可以驻留32个线程束即最多32*321024个线程一个SM可以运行多个线程块如线程块有16个线程那么一个SM可以同时运行两个线程块。1、线程束内基本函数unsigned __ballot_sync(unsigned mask, int predicate);int __all_sync(unsigned mask, int predicate);int __any_sync(unsigned mask, int preducate);T __shfl_sync(unsigned mask, T v, int srcLane, int w warpSize);T __shfl_up_sync(unsigned mask, T v, unsigned d, int w warpSize);T __shfl_down_sync(unsigned mask, T v, unsigned d, int w warpSize);T __shfl_xor_sync(unsigned mask, T v, int laneMask, int w warpSize);__syncwarp();reduce_shfl();2、协作组-线程块片函数unsigned __ballot_sync(int predicate);int __all_sync(int predicate);int __any_sync(int predicate);T __shfl_sync(T v, int srcLane);T __shfl_up_sync(T v, unsigned d);T __shfl_down_sync(T v, unsigned d);T __shfl_xor_sync(T v, int laneMask);七、常用cuda库Thrust类似于C的标准模板库standard template librarycuBLAS基本线性代数子函数basic liner algebra subroutinescuFFT快速傅里叶变换fast Fourier transformscuSPARSE稀疏sparse矩阵cuRAND随机数生成器rendom number generatorcuSolver稠密dense矩阵和稀疏矩阵计算库cuDNN深度神经网络deep neural networks八、context、stream、event流是一种基于context之上的任务管道抽象未显式调用函数创建stream时使用默认streamdefault stream在一个stream里的执行步骤都是顺序的可以是阻塞也可以是非阻塞如下示例cudaMemcpy(d_x, h_x, M, cudaMemcpyHostToDevice); cudaMemcpy(d_y, h_y, M, cudaMemcpyHostToDevice); sumgrid_size, block_size(d_x, d_y, d_z, N); cudaMemcpy(h_z, d_z, cudaMemcpyDeviceToHost);stream并行实现计算与通信重叠通过创建stream可以同时运行多个CUDA stream多个stream可实现核函数和通信的并行执行stream的用法如下1、创建stream cudaError_t cudaStreamCreate(cudaStream_t *); // 创建stream cudaError_t cudaStreamDestroy(cudaStream_t); // 销毁stream 2、使用stream xxx_kernelgrid_size, block_size(函数参数): xxx_kernelgrid_size, block_size, SharedMemorySize(函数参数): xxx_kernelgrid_size, block_size, SharedMemorySize, stream_id(函数参数): 3、等待完成 cudaError_t cudaStreamSynchronize(cudaStream_t stream); // 阻塞等待完成 cudaError_t cudaStreamQuery(cudaStream_t stream); // 非阻塞检查完成状态 一个完成的示例如下 int main(){ int device_id 0; checkRuntime(cudaSetDevice(device_id)); cudaStream_t stream nullptr; checkRuntime(cudaStreamCreate(stream)); //创建一个流 // 在GPU上开辟空间 float* memory_device nullptr; checkRuntime(cudaMalloc(memory_device, 100 * sizeof(float))); // 在CPU上开辟空间并且放数据进去将数据复制到GPU float* memory_host new float[100]; memory_host[2] 520.25; // 异步复制操作主线程不需要等待复制结束才继续 checkRuntime(cudaMemcpyAsync(memory_device, memory_host, sizeof(float) * 100, cudaMemcpyHostToDevice, stream)); // 在CPU上开辟pin memory,并将GPU上的数据复制回来 float* memory_page_locked nullptr; checkRuntime(cudaMallocHost(memory_page_locked, 100 * sizeof(float))); checkRuntime(cudaMemcpyAsync(memory_page_locked, memory_device, sizeof(float) * 100, cudaMemcpyDeviceToHost, stream)); // 异步复制操作主线程不需要等待复制结束才继续 printf(%f\n, memory_page_locked[2]);//结果是0因为还没等待结果返回 checkRuntime(cudaStreamSynchronize(stream)); //统一等待流队列中的结果 printf(%f\n, memory_page_locked[2]); // 释放内存 checkRuntime(cudaFreeHost(memory_page_locked)); checkRuntime(cudaFree(memory_device)); checkRuntime(cudaStreamDestroy(stream)); delete [] memory_host; return 0; }event用以监控stream是否到达了某个检查点可实现多个stream同步举例说明如下在stream 1上面执行kernel 1 和 kernel 3在stream 2上面执行kernel 2但是必须等到stream 1上面的kernel 1执行结束之后才能开始// Create streams and event cudaStream_t stream1, stream2; cudaEvent_t event1; cudaEventCreate(event1); // Execute kernel1 in stream1 kernel1gridDim, blockDim, 0, stream1(d_data1, repeat); cudaEventRecord(event1, stream1); // Record event1 after kernel1 execution in stream1 // Execute kernel2 in stream2, waiting for event1 cudaStreamWaitEvent(stream2, event1, 0); kernel2gridDim, blockDim, 0, stream2(d_data1, repeat); // Execute kernel3 in stream1 on a different array kernel3gridDim, blockDim, 0, stream1(d_data2, repeat); // Synchronize streams cudaStreamSynchronize(stream1); cudaStreamSynchronize(stream2); // Free device memory and destroy streams and event cudaStreamDestroy(stream1); cudaStreamDestroy(stream2); cudaEventDestroy(event1);九、统一内存1、动态统一内存在HOST端使用cudaMallocManaged()函数进行申请使用cudaFree()函数释放HOST即Device端使用时无需进行Memory Copy而直接使用如下示例int main(void) { const int N 100000000; const int M sizeof(double) * N; double *x, *y, *z; CHECK(cudaMallocManaged((void **)x, M)); CHECK(cudaMallocManaged((void **)y, M)); CHECK(cudaMallocManaged((void **)z, M)); for (int n 0; n N; n) { x[n] a; y[n] b; } const int block_size 128; const int grid_size N / block_size; addgrid_size, block_size(x, y, z); CHECK(cudaDeviceSynchronize()); check(z, N); CHECK(cudaFree(x)); CHECK(cudaFree(x)); CHECK(cudaFree(x)); return 0 }2、静态统一内存使用__device__ __managed__进行修饰如下示例#include stdio.h __device__ __managed__ int ret[1000]; __globle__ void AplusB(int a, int b) { ret[threadIdx.x] a b threadIdx.x; } int main(void) { AplusB1, 1000(10, 100); CHECK(cudaDeviceSynchronize()); for (int i 0; i 1000; i) { printf(%d: AB %d\n, i, ret[i]); } return 0 }3、统一内存可以申请超出实际内存的容量因为实际使用时才会涉及到物理内存类似缺页异常申请的统一内存可以使用gpu_touch()核函数进行全部内存的初始化如果申请了超量的统一内存使用gpu_touch()核函数进行初始化时在超量的部分Memory会初始化失败4、统一内存如果涉及到HOST MemoryDevice Memory如果Device不访问这段统一内存那么HOST只能访问到HOST部分的内存及时让Device使用cudaMemAdvise()/cudaMemPreftchAsync()函数同步一下统一内存HOST才能访问到全部的统一内存参考代码如下int main(void) { int device_id 0; CHECK(cudaGetDevice(device_id)); const int N 100000000; const int M sizeof(double) * N; double *x, *y, *z; CHECK(cudaMallocManaged((void **)x, M)); CHECK(cudaMallocManaged((void **)y, M)); CHECK(cudaMallocManaged((void **)z, M)); for (int n 0; n N; n) { x[n] a; y[n] b; } const int block_size 128; const int grid_size N / block_size; CHECK(cudaMemPrefetchAsync(x, M, device_id, NULL)); CHECK(cudaMemPrefetchAsync(y, M, device_id, NULL)); CHECK(cudaMemPrefetchAsync(z, M, device_id, NULL)); addgrid_size, block_size(x, y, z); CHECK(cudaFree(x)); CHECK(cudaMemPrefetchAsync(z, M, cudaCpuDeviceId, NULL)); CHECK(cudaDeviceSynchronize()); check(z, N); CHECK(cudaFree(x)); CHECK(cudaFree(y)); CHECK(cudaFree(z)); return 0; }十、重点cuda多线程基础1、thread、block、grid和warpcuda内存模型2、内存模型3、统一内存可用于rdma吗4、多卡统一内存编程5、纹理内存与动态并行cuda同步6、多流编程event实现显示同步7、异步操作时怎么知道操作完成的8、事件同步与流同步9、节点间怎么划分流流之间怎么同步10、同步和原子操作11、对⽐__threadfence()、__threadfence_block()、__syncthreads()和cudaDeviceSynchronize()cuda卡间通信12、统一内存与cudaEnablePeerAccess()13、cuda程序调用ncclrdma场景编程使用nccl14、nvsharemem使用15、编程实现rdma跨卡传输显存数据16、cudaMemcpyAsync()与cudaMemcpyPeer()与多卡统一内存cuda其他17、张量tensor core编程18、rl详细训练推理流程多卡nccl训练和推理流程19、cuda编写深度学习训练代码20、onnx runtime。十一、疑问1、核函数怎么被加载到gpugpu怎么运行核函数2、runtime/driver api怎么与KMD交互3、卷积、激活、池化、归一化、标量、向量、矩阵、张量GPU软件抽象与硬件映射的理解Grid、Block、Warp、Thread与SM、SPGPU架构GPU架构与通信互联技术介绍CUDA运行APIRuntimeAPINVIDA CUDA-DirverAPI入门具体化讲解cuda runtime api是什么runtime driver是什么【YOLO系列】YOLOv5超详细解读源码详解入门实践改进一文读懂cuda stream与cuda event一文说清楚DeePSeek用的PTX与CUDA的区别自定义CUDA实现PyTorch算子的四种简单方法PhD 第四学期 年中随笔矩阵分解之: 特征值分解(EVD)、奇异值分解(SVD)、SVDcuda runtime/driver API解析【CUDA】Driver API 和 Runtime APIhttps://www.zhihu.com/people/li-wei-27-70-68/posts[CUDA]UVM机制的原理CUDA IPC 是什么CUDA Context IPC进程间通信
延伸阅读

更多相关文章

2026/9/18 11:27:01

RS232/RS485/TTL与串口服务器选型实战:从电平原理到NCOM880T配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 11:27:01

数据结构期末考点锚点解构:从教材到试卷的命题指纹

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 12:52:07

Photoshop核心概念复盘:从分辨率、图层蒙版到路径工具全解析

简介:Photoshop CS(PS)基础知识教程与经典实例教程是一份面向零基础与初级用户的PDF电子文档,定位于帮助读者快速熟悉PS界面结构,理解像素、分辨率、点阵图与矢量图、设备分辨率、位分辨率、颜色模式(RGB、…

2026/9/18 12:52:07

PDF书签修复与合并拆分:PDF补丁丁免费工具箱完整指南

PDF书签修复与合并拆分:PDF补丁丁免费工具箱完整指南 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱,可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档,探查文档结构,提取图片、转成图片等等 项目地址: https://git…

2026/9/18 12:52:07

三维场景性能优化实战:平衡画质与流畅度的完整指南

如果你也是做三维场景、数字展厅、Web3D可视化这类项目的,应该对“好看和性能打架”这事深有体会。模型贴图一上,画面是精致了,帧率却肉眼可见地往下掉;反过来狠心砍几刀美术资源,又觉得画面不够高级,交付时…

2026/9/18 12:52:07

WebGPU 与 DeepSeek-R1 浏览器端 AI 对话应用实战

现在做内部工具的人越来越多,都想把 AI 问答能力嵌进自己的页面里,但真动手时会发现几个绕不开的坎:数据不想出内网、调云端接口有成本、离线环境直接不可用。端侧 AI 就是冲着这几个问题来的。这篇笔记记录的是我用DeepSeek-R1蒸馏模型配合W…

2026/9/18 12:47:07

智能文献助手:NLP技术提升学术论文引用效率

1. 项目背景与核心价值去年帮导师审阅研究生论文时,发现90%的文献引用问题都集中在两个环节:参考文献查找不全和标注格式错误。这直接催生了这个工具的诞生——一个能自动完成学术论文"文献检索→内容关联→标准标注"全流程的智能助手。传统文…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/18 0:01:09

Google Colab 实战:运行模型、数据加载与报错排查

1. 为什么我劝你先搞懂 Colab 的运行模型1.1 Colab 到底是什么,跟本地跑代码差在哪Google Colab 简单说就是一台跑在浏览器里的 Linux 虚拟机,你打开一个 Notebook,背后就连上了一台带 GPU 的远程机器。你在单元格里敲的每一行 Python&#x…

2026/9/18 0:01:09

C语言数据类型与表达式详解

1. C语言数据与数据类型概述在C语言编程中,数据是程序处理的核心对象。理解数据的分类和特性是掌握C语言的基础。C语言中的数据主要分为四大类:常量、变量、表达式和函数。这些数据类型构成了C语言程序的基本元素,每种类型都有其独特的特性和…

2026/9/18 0:01:09

SQL时间字段指定时间段查询:区间语义、索引与时区避坑

上周排查一个线上问题&#xff0c;用户反馈"昨天的订单一条都没查到"&#xff0c;但数据库里明明躺着两千多条。最后定位下来&#xff0c;不是数据丢了&#xff0c;也不是接口挂了&#xff0c;而是那个查询条件把时间段写成了> 2024-05-20 00:00:00 AND < 2024…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码