我目前正在编写一个OpenCL内核(但我认为在CUDA中将是相同的),目前我尝试优化NVidia GPU。
我目前在我的内核中使用63个寄存器,这个内核非常大,所以它使用所有的GPU寄存器。我正在寻找一些方法:
1)查看哪些变量在寄存器中,哪些变量在全局存储器中(因为如果我没有足够的寄存器,编译器似乎将变量保存在全局存储器中)。
2)有没有办法指定哪个变量更重要(或哪个变量应该在寄存器中)。因为我使用了一些存在但较少使用的变量。优先考虑的方法吗?
当我们已经使用所有寄存器时,还有其他优化策略吗?
BTW:我也尝试读取PTX代码并搜索所有“.reg”关键字,但问题是PTX不可读,我不知道哪个寄存器用于代码中的哪个变量。我没有办法找到相应的信息!感谢
答案 0 :(得分:3)
(1)它被称为寄存器溢出。除了检查SASS程序集之外,我认为没有办法找出哪些变量溢出。 OpenCL首先被编译为PTX,这是一个具有无限数量寄存器的虚拟机(没有溢出)。有关详细信息,请参阅NVIDIA演示文稿Local Memory and Register Spilling。
(2)在声明您不想保留在寄存器中的变量时,可以尝试使用volatile
关键字。 volatile
将强制编译器将变量推送到内存,而不是在操作之间的寄存器中携带它。
答案 1 :(得分:2)
查看哪些变量在寄存器中,哪些变量在全局中 存储器
为此,我不知道如何检查它,但是
有没有办法指定哪个变量更重要
当我看到我已经泄漏寄存器(由于缺少它们或者当我需要在本地变量中使用动态索引,这很糟糕)时,我使用的一个技巧是明确存储一些,我认为不是这样的关键,进入本地内存(在CUDA中称为“共享”)
e.g。之前:
uint16 somedata;
后:
__local uint16 somedata[WG_SIZE]; // or __local uint someadata[16];
但请注意,如果您的本地内存使用量会大大增加,您可能会受到惩罚,因为机上波前的数量会减少(即您的入住率会降低)
希望这有帮助。
答案 2 :(得分:1)
如果没有看到代码,尝试“强制”使用寄存器的一种方法是在有限的范围内使用本地副本。 也许只有部分变量在代码的给定部分中被访问。然后,您可以在范围中声明新变量并密集使用它们。没有保证,但我知道它有时会有所帮助。
int a, b, d;
double x,y;
...
{
int ra = a; // copy into new variables more likely to be kept in registers
double rx = x;
... use rx and ra ...
a = ra;
b = rx; // copy back.
}
...