1. Introduction

本文介绍了NVIDIA GPU寄存器的相关内容。

2. GPU寄存器

2.1 物理寄存器的映射

关于gpu寄存器之前我还整理过:GPU寄存器

一个程序的近机器语言级别的中间语言中适用的寄存器,我们称之为“体系结构寄存器,architected register”,这些寄存器会被处理器映射到物理寄存器(Physical Registers)上。

CPU使用寄存器重命名(register renaming)和寄存器重命名表(Register Rename Table)来实现的映射,而GPU采用的方法更简单:

Y = X + B

B是分配给block的寄存器中不同warp的基地址,X是architected register的序号(在一个block中寄存器的偏移量),得出的Y即为物理寄存器的序号。

这个简单的分配方法避免了寄存器重命名的代价,因为GPU并行的线程非常多,和CPU是不同的模型。

分配给warp的寄存器在其生命周期里是固定保留的,(B在warp执行过程中是常量),只有在这个warp所属的CTA(Cooperative Thread Array)执行完,分给它的寄存器才会释放。

2.2 寄存器生命周期

如果一个寄存器的值后面会被用到,那么这个寄存器就是“活的”(live)。

一个kernel使用的寄存器数量 = 每个thread使用的寄存器数量 × thread数

而每个thread使用的寄存器数量,则取决于这个kernel运行时同时处于生命周期的寄存器数量的最大值。

使用nvidisasm或者cuobjdump可以输出kernel 中寄存器的生命周期状态,但实际上输出结果是串行思维来看的,仅供参考,可以说是错误的。

3. CUDA不同编译阶段的寄存器分配

nvcc编译过程可以简单看成两部分,CUDA C --》 PTX --》Binary,PTX 是一个底层的描述并行线程处理的指令集架构(不知道官方文档中说的ptx是virutal machine是什么意思)。CUDA编译器使用SSA(static single assignment)形式生成的PTX文件,即每个变量都对应一个虚拟寄存器。然后再通过ptxas编译成二进制,在二进制中的寄存器,即为architected register,与物理寄存器一一对应。

CUDA二进制可以通过官方的nvdisasm或者cuobjdump反编译成人类可读的SASS文件,语法类似常见的汇编。但是官方没有提供将SASS重新编译成二进制的工具,github上有开源的maxas,不过学习门槛很高,而且支持的架构和指令有限。

Reference

[1]李男,庞建民,单征.基于特征向量匹配的CUDA程序PTX代码提取[J].信息工程大学学报,2014,15(05):628-630.

Confusion with CUDA PTX code and register memory

nvidia binary utilities, cuobjdump, nvdisasm

RegMutex: Inter-Warp GPU Register Time-Sharing, ISCA 2018


文章版权归 FindHao 所有丨本站默认采用CC-BY-NC-SA 4.0协议进行授权|
转载必须包含本声明,并以超链接形式注明作者 FindHao 和本文原始地址:
https://findhao.net/academic/2545.html

Comments