3.7 寄存器
寄存器是NVIDIA GPU存储器空间中,最快的硬件,读取它几乎不用耗费时间。因此合理的使用它是至关重要的。
3.7.1 寄存器溢出和本地存储器
由于GPU上寄存器的数目是有限的,在计算能力1.0,1.1的设备上,其数目是8 K,在计算能力1.2,1.3的设备上,其值是16 K。如果我们使用的寄存器数目超过了系统的最大数目,编译器便会将其转入设备存储器上的一个区域内,这个区域称为本地存储器。本地存储器的速度和全局存储器一样。
使用2.3及以前的toolkit,可以使用-keep指令输出中间文件,然后直接查看cubin文件就可以知道内核使用的寄存器数目,同时也能看到共享存储器、常量存储器和本地存储器的使用量。如果使用的是3.0的toolkit,此时cubin文件已经不是文本格式,因此不能直接查看,此时可以在用nvcc 编译的时候,使用—ptxas-options=-v选项,编译器会报告存储器使用信息。
3.8 执行配置和占用率
使用<<<grid, block>>>语法指定执行线程配置的时候,grid 和block大小也影响程序的效率。一般而言,grid要大于多处理器的数目,这样才能让多处理器不至于空闲,但是这样也会导致一些问题,比如负载均衡,如果grid大小不能比sm 数目整除的话,就会有SM计算的时候,另外一些SM空闲,如果grid远大于sm数目的话,可忽略,但是如果SM数目与grid大小相差不大的话,性能损耗就很可观了。一般而言,grid大小至少是sm数目的三倍,如果有块内同步的话,grid要大于sm的四倍以上。一般而言,block大小要是束大小的四倍以上,此时基本上可隐藏访存延迟。如果数据量比较小的话,grid大小和block大小可能相互牵制,此时要综合考虑。在数据量比较大的时候,只要考虑block大小就行了。
另外,CUDA还有一个占用率问题,所谓占用率就是SM上活跃块数目和最大允许数目的比例。使用cuda visual profiler的时候会有这个值。这个值的影响因素有内核内寄存器、共享存储器的用量。由于CUDA线程在切换的时候并不转储线程的状态,这是CUDA线程极轻的原因,但是这也使得为了保证线程能够切换,内核内使用的资源最多只能是最大资源的一半,此时占用率是0.25,一般而言占用率要在0.5左右就可以了。
[ 本帖最后由 yyfn风辰 于 2010-7-2 15:06 编辑 ]