1

我目前正在编写一个 OpenCL 内核(但我想在 CUDA 中会是一样的),目前我正在尝试针对 NVidia GPU 进行优化。

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

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

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

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

顺便说一句:我也尝试阅读 PTX 代码并搜索所有“.reg”关键字,但问题是 PTX 不可读,我不知道哪个寄存器用于我的代码中的哪个变量。我还没有找到任何联系方式!

谢谢

4

3 回答 3

3

(1) 称为寄存器溢出。除了检查 SASS 程序集外,我认为没有办法找出哪些变量会溢出。OpenCL 首先被编译为 PTX,这是一个具有无限数量的寄存器(无溢出)的虚拟机。有关详细信息,请参阅 NVIDIA 演示本地内存和寄存器溢出

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

于 2012-10-04T14:12:49.450 回答
2

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

为此,我不知道如何检查它,但是

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

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

例如之前:

uint16 somedata;

后:

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

但请注意,如果您的本地内存使用量将大大增加,您可能会受到惩罚,因为飞行波前的数量会减少(即您的占用率可能较低)

希望这可以帮助。

于 2013-01-05T15:43:10.733 回答
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.
}

...
于 2012-10-05T07:18:35.593 回答