cuda02-cuda编程模型  nvprof
文章目录1 软硬件架构知识2 kernel执行的性能部分3 并行性能表现3.1 线程束分支效率1 - 分化分支 / 分支数3.2 SM的实际占用率活跃的warp数量 / SM支持最大并发warp数量3.3 全局内存读取速度全局内存读取字节数 / 内核执行时间s3.4 全局内存读取效率实际使用的全局内存加载字节数 / 总全局内存加载字节数)3.5 线程束上指令数平均值指标越小越好越大可能是指令分化。3.6 线程束被阻塞的比例同步导致的线程停顿和__syncthreads()有关 )3.7 全局内存的写入吞吐量存储的全局内存数据量 / 执行时间s3.8 DRAM读取数据的吞吐量3.9 全局内存读取事务3.11 全局内存每次加载或储存所需的内存事务数3.10 全局内存写事务3.11 共享内存读写事务数量3.12 暂时没有用到的指标4 同步4.1 __syncthreads:4.2 cudaDeviceSynchronize():4.3 *warp内32个线程存在隐士同步*5 使用nsight compute测试性能博主公司重组求推荐大模型部署ai infra base上海的工作。my phone 156012371031 软硬件架构知识cuda 内存中最重要的是cuda的共享内存和全局内存。全局内存大概几个GB访问速度慢声明周期是整个内核的执行期间。shared memory是SM流式处理器上的高速内存只有十几KB一个block中所有的thread都可以访问。执行速度块声明周期短仅在当前block执行期间存在。shared memory的大小一般是固定的比如32KB// 这里是一个使用共享内存的例子__global__ voidkernel(float*A,float*B,float*C){int idxthreadIdx.xblockIdx.x*blockDim.x;// 将数据从全局内存加载到共享内存__shared__ float shared_A[THREAD_NUM];shared_A[threadIdx.x]A[idx];__syncthreads();// 在共享内存上进行计算shared_A[threadIdx.x]*2;__syncthreads();// 将结果写回全局内存C[idx]shared_A[threadIdx.x];}同一个block中的线程可以使用共享内存通讯不同block中的内存只能使用全局内存通讯。cudaMemcpy是隐式同步操作host会被阻塞到内存操作结束。cudaDeviceSynchronize 会阻塞设备的所有请求操作。nsight compute用于分析launch的kernel nsight systems用于分析程序整体流程。MFLOPS代表每秒百万次浮点运算 GFLOPS代表每秒十亿次浮点运算TFLOPS代表每秒万亿次浮点运算OPS 是 Operations Per Second 的缩写TOPS 代表每秒进行一万亿次运算。我的板卡的算力是 1.13TFLOPS, Pascal架构 显存带宽是48.1GB/s SM数量3。华为昇腾910算力 320TFLOPfp16, 640TOPSint8HBM带宽为400GB/s鲲云caisa4.0 算里 16TOPSint8关于cuda中的索引threadIdx.x// 线程在块中的索引第几个线程blockIdx.x// block在grid中的索引第几个blockblockDim.x// block在x轴上的维度x轴方向上有多少个线程gridDim.x// grid在x轴上有多少个blockblockDim.x*gridDim.x// x轴上的thread总数dim3的结构的定义dim3block(3);dim3grid((nElemblock.x-1)/block.x);printf(grid.x %d,grid.x);// grid是dim3实例,grid.x表示x轴上的block的数量printf(block.x %d,block.x);// block是dim3,block.x表示x轴上thread的数量关于二维抽象矩阵的索引这里的索引是为了把线程和块的索引映射到矩阵上只是一种抽象概念。idxthreadIdx.xblockIdx.x*blockDim.x idythreadIdx.yblockIdx.y*blockDim.y内存一维索引这里是为了将矩阵坐标映射到全局内存上硬件中的内存是线性存储的。idxidy*nxidx这里有一张blockthread索引-坐标(ix, iy)-全局内存索引(ifx)的对应关系图。一个不错的实用索引图SM中的重要组件cuda核心寄存器文件存放数组常量索引kernel中定义的变量local memory(较大的结构体和本地数组寄存器无法存放的变量)const memory(SM中有专门的const mem用__const__来声明)共享内存__shared__修饰 shared memory在kernel函数中声明生命周期和现成块一致一级缓存warp调度器指令分发单元加载存储单元不理解todo存储器作用域声明期RegisterThreadKernelLocal MemoryThreadKernelShared MemoryBlockKernelGlobal MemoryGridApplicationConstantGridApplication2 kernel执行的性能部分不同的grid和block配置速度也会不同sumMatrixOnGPU-2D.cu的速度测试使用sys/time.h中的函数gettimeofday测试非nvprof工具。二维grid 二维block的速度 单位s sumMatrixOnGPU2D add matrix at device 0.003266 sumMatrixOnGPU2D (512,1024), (32,16) 一维grid 一维block的速度 sumMatrixOnGPU1D add matrix at device 0.000003 sumMatrixOnGPU1D (128,1), (128,1) 二维grid 一维block的速度 sumMatrixOnGPU2dGrid1dBlock add matrix at device 0.000001 sumMatrixOnGPU2dGrid1dBlock (64,16384), (256,1)item含义block.x, block.yblock是dim3的定义表示一个线程块在xy轴上的维度即xy轴上有多少个线程。blockDim.x表示每个线程块在x维度上的线程数。blockIdx.x表示当前线程块在网格中的x维位置。threadIdx.x表示当前线程在其线程块内的x维索引。warp线程束是一个抽象的概念数量是32.SIMD, SIMT一个不同点SIMD要求所有的线程要求所有元素在一个统一的同步组中执行SIMT允许线程束中多个线程独立执行。SIMT中每个线程可以有自己的寄存器状态。线程块之内所有的线程有同步的方法保证线程块所有的线程都能同步完成但是没有线程块之间的同步方法。多个线程块可以分配到同一个SM中。Fermi架构中一个SM含有32个CUDA核心SM有两个线程束调度器和两个指令调度单元。当一个线程block被指定给一个SM时block中所有的线程被分成线程束两个调度器选择两个线程束再把一个指令从线程束中发到一个组上组里有16个 CUDA核心16个加载/ 存储单元。 Fermi架构每个SM可以同时处理48个线程束即可以在一个SM上同时常驻1536个线程。3种常见限制内核性能的因素存储带宽计算资源指令和内存延迟防止线程束分化的一个小技巧 if((tid/warpSize) % 2 0) 如果可能以warp为单位安排if…else分支可以避免线程束中任务分化。NVCC编译的用-g -G停止编译器的优化用工具nvprof --metrics branch_efficiency ./app 可以测试得到具体的branch效率 另外发现-O0无法停止分支预测。SM中有多个线程束从一个线程束切换到另一个线程束是没有开销的线程束的整个生命周期都是保存在芯片内的。SM中线程束的数量是由线程消耗的共享内存和寄存器决定的。高效内核的原则 1- 保持每个块中的线程数量是32的倍数。 2- 避免块太小块至少有128或256个线程。 3- 块的数量要多于SM的数量SM需要多个块保持活跃。4- 实验得到最佳的执行配置。3 并行性能表现3.1 线程束分支效率1 - 分化分支 / 分支数nvprof--metrics branch_efficiency./simpleDivergence Invocations Metric Name Metric Description Min Max Avg DeviceNVIDIA GeForce MX150 (0)Kernel:mathKernel1(float*)1branch_efficiency Branch Efficiency83.33%83.33%83.33%Kernel:mathKernel2(float*)1branch_efficiency Branch Efficiency100.00%100.00%100.00%Kernel:mathKernel3(float*)1branch_efficiency Branch Efficiency100.00%100.00%100.00%3.2 SM的实际占用率活跃的warp数量 / SM支持最大并发warp数量nvprof--metrics achieved_occupancy./sumMatrix Invocations Metric Name Metric Description Min Max Avg DeviceNVIDIA GeForce MX150 (0)Kernel:sumMatrixOnGPU2D(float*,float*,float*,int,int)1achieved_occupancy Achieved Occupancy0.8130790.8130790.813079提高SM实际占用率的思路增加block并发的数量优化block大小通常128,256,512, block太大无法同时并行多个block。block太小SM利用率不足。减少block中寄存器的使用变量可以考虑放在全局内存中。减少非必要的共享内存的使用。增加计算密度比如做循环展开增加计算操作和内存访问比率。如果kernel是内存访问密集的可以考虑使用共享内存或者常量内存来缓存数据。3.3 全局内存读取速度全局内存读取字节数 / 内核执行时间snvprof--metrics gld_throughput./sumMatrix Invocations Metric Name Metric Description Min Max Avg DeviceNVIDIA GeForce MX150 (0)Kernel:sumMatrixOnGPU2D(float*,float*,float*,int,int)1gld_throughput Global Load Throughput2.3684GB/s2.3684GB/s2.3684GB/s3.4 全局内存读取效率实际使用的全局内存加载字节数 / 总全局内存加载字节数)nvprof--metrics gld_efficiency./sumMatrix Invocations Metric Name Metric Description Min Max Avg DeviceNVIDIA GeForce MX150 (0)Kernel:sumMatrixOnGPU2D(float*,float*,float*,int,int)1gld_efficiency Global Memory Load Efficiency100.00%100.00%100.00%3.5 线程束上指令数平均值指标越小越好越大可能是指令分化。下面例子中reduceNeighbored的指令数是reduceNeighboredLess的两倍多797.25 vs 355.56 ).nvprof--metrics inst_per_warp./reduceInteger Invocations Metric Name Metric Description Min Max Avg DeviceNVIDIA GeForce MX150 (0)Kernel:reduceNeighbored(int*,int*,unsignedint)1inst_per_warp Instructions per warp797.250000797.250000797.250000Kernel:reduceNeighboredLess(int*,int*,unsignedint)1inst_per_warp Instructions per warp355.562500355.562500355.5625003.6 线程束被阻塞的比例同步导致的线程停顿和__syncthreads()有关 )可以看到最后5次迭代线程束展开后阻塞比例降低最后6个stride展开后使用的__syncthreads减少nvprof--metrics stall_sync./reduceInteger Kernel:reduceUnrolling8(int*,int*,unsignedint)1stall_sync Issue StallReasons(Synchronization)39.87%39.87%39.87%Kernel:reduceUnrollWarps8(int*,int*,unsignedint)1stall_sync Issue StallReasons(Synchronization)24.10%24.10%24.10%3.7 全局内存的写入吞吐量存储的全局内存数据量 / 执行时间snvprof--metricsgst_throughput ./app3.8 DRAM读取数据的吞吐量dram_read_throughput 更广泛它包括所有与 DRAM 相关的读取操作不仅限于全局内存读取gld_throughput还可能包括其他类型的内存读取例如共享内存或常量内存。据说dram_read_transactions包含gld_ghroughput.DRAM是out-chip, DRAM包含全局内存常量内存纹理内存本地内存onchip的内存寄存器共享内存。3.9 全局内存读取事务单位事务次数通常表示为“次数”transactionsnvprof--metrics gld_transactions./appgld_transactions 反映了对内存进行访问的次数而gld_throughput 关注的是数据传输的速率。例子Kernel:reduceSmem(int*,int*,unsignedint)gld_transactions Global Load Transactions838861083886108388610gst_transactions Global Store Transactions1310721310721310723.11 全局内存每次加载或储存所需的内存事务数nvprof--metrics gld_transactions_per_request,gst_transactions_per_request./appKernel:copyGmem(float*,float*,int,int)gld_transactions_per_request Global Load Transactions Per Request16.00000416.00000416.000004gst_transactions_per_request Global Store Transactions Per Request4.0000004.0000004.0000003.10 全局内存写事务nvprof--metrics gst_transactions./app3.11 共享内存读写事务数量共享内存容易出现bank冲突但是这里的事务数大意味着数据分布比较差和bank冲突没有直接关系。比如做transpose时候使用共享内存按照行写共享内存按照列读取共享内存warp内就会出现bank串行访问的冲突需要多个内存事务完成呢个。// shared memory 读操作nvprof--metrics shared_load_transactions_per_request./app// 写操作nvprof--metrics shared_store_transactions_per_request./app输出结果如Kernel:setRowReadRow(int*)shared_load_transactions_per_request Shared Memory Load Transactions Per Request1.0000001.0000001.000000shared_store_transactions_per_request Shared Memory Store Transactions Per Request1.0000001.0000001.000000Kernel:setColReadCol(int*)shared_load_transactions_per_request Shared Memory Load Transactions Per Request32.00000032.00000032.000000shared_store_transactions_per_request Shared Memory Store Transactions Per Request32.00000032.00000032.000000最理想情况一个请求只发出一个内存事务。setColReadCol的内存事务是32因为出现储存体bank冲突。3.12 暂时没有用到的指标ipc:每个周期执行的指令 issued_ipc:每个周期发出的指令 flop_hp_efficiency:实现的半精度浮点运算与理论峰值的比值 l2_utilization:L2 缓存利用率相对于理论峰值利用率的级别范围为0到10inst_fp_32:非谓词线程算术、比较等执行的单精度浮点指令数 stall_texture:由于纹理子系统被充分利用或有太多未完成的请求而发生的停顿百分比 local_load_throughput:本地内存加载吞吐量 local_store_throughput:本地内存存储吞吐量 shared_load_throughput:共享内存负载吞吐量 shared_store_throughput:共享内存存储吞吐量 shared_store_transactions:共享内存存储事务数 shared_load_transactions_per_request:每次共享内存加载时执行的平均共享内存加载事务数 inst_replay_overhead:每条指令执行的平均重放次数 warp_execution_efficiency:每个 warp 的平均活动线程数与 SM 支持的每个 warp 的最大线程数之比 inst_per_warp:每个 warp 执行的平均指令数nvprof metrics指标官方介绍4 同步4.1 __syncthreads:用来保证一个线程块中所有的线程操作都完成。4.2 cudaDeviceSynchronize():用来保证设备上所有的cuda操作完成。线程块之间没有同步指令只能串行启动内核。4.3warp内32个线程存在隐士同步warp内的线程必须要保证同步运行。5 使用nsight compute测试性能todo

相关新闻

Krea-2 Turbo模型深度实践指南:如何在有限硬件资源下实现专业级AI绘图

Krea-2 Turbo模型深度实践指南:如何在有限硬件资源下实现专业级AI绘图

Krea-2 Turbo模型深度实践指南:如何在有限硬件资源下实现专业级AI绘图 【免费下载链接】Krea-2 项目地址: https://ai.gitcode.com/hf_mirrors/Comfy-Org/Krea-2 你是否曾因显存不足而无法运行高质量的AI绘图模型?或者在使用高端模型时遭遇推理速…

2026/7/4 22:00:50阅读更多 →
三步玩转Sulphur-2:开启无审查AI视频创作新纪元

三步玩转Sulphur-2:开启无审查AI视频创作新纪元

三步玩转Sulphur-2:开启无审查AI视频创作新纪元 【免费下载链接】Sulphur-2-Base-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/vantagewithai/Sulphur-2-Base-GGUF 你是否曾幻想过这样的场景:脑海中闪过一个绝妙的创意画面,只…

2026/7/4 22:00:50阅读更多 →
Ryujinx免费Switch模拟器:终极完整指南,轻松在PC上畅玩Switch游戏

Ryujinx免费Switch模拟器:终极完整指南,轻松在PC上畅玩Switch游戏

Ryujinx免费Switch模拟器:终极完整指南,轻松在PC上畅玩Switch游戏 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 想在电脑上体验《塞尔达传说:旷野…

2026/7/4 22:00:50阅读更多 →
hot100 回文链表(234)

hot100 回文链表(234)

本算法采用快慢指针定位、局部链表反转与双指针线性比对的组合方案解决“回文链表”判定问题。其核心本质是在不开辟额外存储空间的前提下,通过修改原链表后半段的拓扑结构实现前后数据的空间对齐。当前提供的源码实现了时间复杂度 O(n) 和额外空间复杂度 O(1) 的最…

2026/7/4 22:56:02阅读更多 →
遗传算法工程实战:选择、交叉、变异与终止的四大核心调优

遗传算法工程实战:选择、交叉、变异与终止的四大核心调优

1. 这不是教科书里的遗传算法,而是我调试了73次后才敢写的实操指南“遗传算法”这四个字,听上去像生物课上讲DNA双螺旋时顺带提的一句术语,又像AI面试题里那个永远答不全的“请手推GA流程”。但真实情况是:我在工业缺陷检测项目里…

2026/7/4 22:56:02阅读更多 →
STM32L021K4与LV30条码扫描器的低功耗嵌入式方案

STM32L021K4与LV30条码扫描器的低功耗嵌入式方案

1. 项目概述:LV30条码扫描器与STM32L021K4的硬件协同方案 在工业自动化、物流管理和零售结算等领域,条码识别系统的可靠性和适应性直接影响着整体效率。LV30作为一款高性能线性条码扫描器,配合STM32L021K4超低功耗微控制器的组合,…

2026/7/4 22:56:02阅读更多 →
智能工具如何提升MBA论文写作效率与质量

智能工具如何提升MBA论文写作效率与质量

1. 学术写作的智能化转型去年帮导师审阅MBA论文时,发现超过60%的参考文献都来自几个特定的智能学术平台。这让我意识到,当代学术研究方式正在经历一场静默革命——过去需要泡图书馆数周才能完成的文献工作,现在通过智能工具组合能在72小时内达…

2026/7/4 22:56:02阅读更多 →
动态环境下多无人机协同路径规划与Matlab实现

动态环境下多无人机协同路径规划与Matlab实现

1. 动态环境下多无人机协同路径规划的核心挑战多无人机系统在动态环境中的协同作业正成为工业巡检、灾害救援等领域的关键技术。与静态环境相比,动态场景引入了三类典型挑战:1.1 环境不确定性的实时处理动态障碍物的运动轨迹预测需要建立概率模型。以移动…

2026/7/4 22:56:02阅读更多 →
IGBT失效机理深度剖析:从现象溯源到设计预防

IGBT失效机理深度剖析:从现象溯源到设计预防

1. IGBT失效现象:从铝层熔化到绑定线烧毁的现场诊断当工程师拆解一台故障的变频器或新能源汽车电机控制器时,IGBT模块内部往往呈现触目惊心的损伤场景。最常见的是芯片表面铝层像火山熔岩般隆起变形,金黄色的绑定线断裂成数截,甚至…

2026/7/4 22:51:02阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/4 14:25:39阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/4 14:57:00阅读更多 →
端到端自动驾驶:从GTC‘26看工程可信落地的核心逻辑

端到端自动驾驶:从GTC‘26看工程可信落地的核心逻辑

1. 项目概述:当算法工程师走进GTC26展厅,看到的不是芯片,而是“端到端”的呼吸节奏“端到端”这三个字,在GTC’26现场出现的频率,高得像NVLink带宽测试时的峰值曲线——它不再是一个论文里的技术路径选项,而…

2026/7/4 0:02:48阅读更多 →
缺牙修复科普:常见义齿类型与选择参考

缺牙修复科普:常见义齿类型与选择参考

缺牙修复科普:常见义齿类型与选择参考牙齿缺失是中老年人群中较为常见的口腔问题,不仅会造成咀嚼不便、进食受影响,长期还可能对营养摄入与日常社交带来困扰。义齿是改善缺牙问题的常用方式,目前市面上的义齿种类较多,…

2026/7/4 0:02:48阅读更多 →
STM32F091RC与LTC6904实现高精度方波信号生成

STM32F091RC与LTC6904实现高精度方波信号生成

1. 项目概述:LTC6904与STM32F091RC的精准方波生成方案在嵌入式系统开发中,精确的时钟信号和定时控制往往是项目成败的关键。LTC6904作为一款低功耗、高精度的可编程振荡器芯片,与STM32F091RC这款ARM Cortex-M0内核微控制器的组合,…

2026/7/4 0:02:48阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/4 1:16:56阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/4 2:33:55阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/4 2:33:55阅读更多 →