OpenCL和CUDA注册使用优化



我目前正在编写一个OpenCL内核(但我认为在CUDA中也是如此),目前我试图为NVidia GPU进行优化。

我目前在我的内核中使用了63个寄存器,这个内核非常大,所以它使用了所有的GPU寄存器。我正在寻找一些方法:

1) 查看哪些变量在寄存器中,哪些在全局内存中(因为如果我没有足够的寄存器,编译器似乎会将变量保存在全局内存)。

2) 有没有办法指定哪个变量更重要(或者哪个应该在寄存器中)。因为我使用了一些存在但使用较少的变量。一种给予优先权的方式?

当我们已经使用了所有寄存器时,是否还有其他优化策略?

BTW:我也试着读取PTX代码并搜索所有的".reg"关键字,但问题是PTX不可读,我不知道代码中的哪个寄存器用于哪个变量。我找不到任何通讯的方法!

感谢

(1)这叫做寄存器溢出。我认为除了检查SASS程序集之外,没有任何方法可以找出哪些变量泄漏了。OpenCL首先被编译到PTX,这是一个具有无限数量寄存器(没有溢出)的虚拟机。有关更多信息,请参阅NVIDIA演示文稿"本地内存和寄存器溢出"。

(2) 在声明不想保留在寄存器中的变量时,可以尝试使用volatile关键字。volatile将强制编译器将变量推出内存,而不是在操作之间将其放入寄存器。

查看哪些变量在寄存器中,哪些变量在全局存储器

为此,我不知道如何检查它,然而

有没有办法指定哪个变量更重要

当我看到我有溢出的寄存器时(由于缺少它们或当我需要在本地变量中使用动态索引时,这很糟糕),我使用的一个技巧是将我认为不那么关键的寄存器显式存储到本地内存中(在CUDA中称为"共享")

例如之前:

uint16 somedata;

之后:

__local uint16 somedata[WG_SIZE]; // or __local uint someadata[16];

但要注意的是,如果你的本地内存使用量将大大增加,你就有可能受到惩罚,因为机上波前的数量将减少(即你可能有较低的占用率)

希望这能有所帮助。

在看不到代码的情况下,尝试"强制"使用寄存器的一种方法是在有限的范围内使用本地副本。也许在代码的给定部分中只访问了一些变量。然后,您可以在一个范围中声明新的变量,并集中使用这些变量。虽然不能保证,但我知道这有时会有所帮助。

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.
}
...

最新更新