我的显卡是RTX 2060 super,其计算能力是7.5。最近发现CUDA提供了自动计算占用率的计算器即CUDA Occupancy Calculator,官网自行下载即可。
我下载下来后,阅读完说明,设置了下图紫色圈中的几个数值。开始想了很久,不知道为何占用率给出竟然是63%,现在已明白,记录在此。
首先,不要忽略绿色圈中的那几个设备特性,我原来一直不知道这几个对占用率有何影响。
1、然后占用率公式大家都知道:每个SM中活跃线程束的数量/每个SM中最大的线程束的数量。可以看到我的设备每个SM中最大线程束是32固定的,所以现在问题变为活跃线程束为什么是20。粉色圈中的部分的最小值才是决定占用率的因素,所以可以看到占用率是由上图中粉色圈中的寄存器因素计算而来。寄存器因素显示:(每个SM有10个活跃blocks)*(每个block有2个线程束)=20.(所以占用率公式的分子即活跃线程束的数量就是这样来的)。
2、所以现在变为寄存器因素中每个SM中活跃blocks为什么是10。也就是浅蓝色C为什么是10。易知,C=B/A。所以此时问题变为A为什么==2,B为什么==20。
3、我查看了下A的公式:=IF(myAllocationGranularity="block",CEILING(CEILING(MyWarpsPerBlock,myWarpAllocationGranularity)*MyRegCount*limitThreadsPerWarp,myAllocationSize),MyWarpsPerBlock) 而绿色圈中显示寄存器分配粒度不是"block",而是warp,所以此时A=myWarpsPerBlock=64/32=2
4、我查看了下B的公式:
=IF(myAllocationGranularity="block",limitRegsPerBlock,FLOOR(limitRegsPerBlock/CEILING(MyRegCount*limitThreadsPerWarp,myAllocationSize),myWarpAllocationGranularity)) 而绿色圈中显示寄存器分配粒度不是"block",而是warp,所以此时B=FLOOR(limitRegsPerBlock/CEILING(MyRegCount*limitThreadsPerWarp,myAllocationSize),myWarpAllocationGranularity) 代入我紫色圈中的设置数值后:
所以到此为止,就知道ABC三处是怎么计算的了。
5、关于warps的B位置为什么是32,我看了下公式:max warps per SM即查灰色部分的设备特性可知=32。
总结:反正遇到不会的地方很多时候还是得靠自己查自己想自己查这样反复,因为网上常常没有答案甚至很多人的答案是错的。反正是CUDA提供的自动计算器,点开单元格就知道公式了。 网上很多人讲的都是错的,而且不要寄希望于一些CUDA群,都是一群僵尸。