OpenCl寄存器的幻数 我写了两个不同的OpenCL内核,使用英伟达剖析器来获取它们的一些信息,发现两个工作项都使用63个寄存器。p>

OpenCl寄存器的幻数 我写了两个不同的OpenCL内核,使用英伟达剖析器来获取它们的一些信息,发现两个工作项都使用63个寄存器。p>,opencl,nvidia,Opencl,Nvidia,我想尽一切办法来降低这个数字(用ushort替换int,试图在{}内声明变量以显示编译器何时可以去掉它们),但似乎不可能改变这个数字 然后我发现了他写的一个内核,它再次使用了63个寄存器 当然,这可能纯粹是巧合,但可能有一个背后的原因…使用的特定功能,硬件限制?有人知道吗?寄存器/线程的最大数量受硬件限制,取决于设备的“计算能力”。看看这张桌子 . (这适用于NVidia,其他供应商可能有其他限制)。63寄存器是大多数最新硬件(如GTX 480到GTX 770)上的最大数量。只有GTX 780

我想尽一切办法来降低这个数字(用ushort替换int,试图在{}内声明变量以显示编译器何时可以去掉它们),但似乎不可能改变这个数字

然后我发现了他写的一个内核,它再次使用了63个寄存器


当然,这可能纯粹是巧合,但可能有一个背后的原因…使用的特定功能,硬件限制?有人知道吗?

寄存器/线程的最大数量受硬件限制,取决于设备的“计算能力”。看看这张桌子 .


(这适用于NVidia,其他供应商可能有其他限制)。

63寄存器是大多数最新硬件(如GTX 480到GTX 770)上的最大数量。只有GTX 780或特斯拉K20,每个线程才能获得255个寄存器

因此,当内核使用63个寄存器时,很可能会使用63个以上的寄存器,但它们会溢出到片外专用内存(也称CUDA本地内存)。例如,如果您的nvidia探查器报告了128字节的本地内存,这意味着您需要去掉32个(溢出的)寄存器,然后才能得到低于63个硬件寄存器


顺便说一句:“8192每个多处理器32位寄存器”是指驻留在多处理器上的所有工作组的8192个寄存器。但通常工作组的数量受工作组的大小和内核需要的寄存器数量的限制。例如,如果内核使用63个寄存器,并且工作组大小为16^2,则每个工作组的寄存器数为:63*16^2=16128。假设每个多处理器有64K个寄存器,然后,您可以在每个多处理器上驻留4个工作组,这将产生25%的占用率。

为什么您认为使用
ushort
而不是
int
将减少使用的寄存器数量?因为寄存器用于存储经常使用的变量,从而避免对全局/本地内存进行代价高昂的访问。因此,如果存储float和ushort而不是double和int,则可以节省一些空间。我尝试了一个简单的内核,有效地看到使用一个新的双变量使用了两个寄存器,这是有意义的,因为寄存器是32位的,双变量是64位的。从64位到32位时保存寄存器,这是正确的。然而,由于寄存器无论如何都是32位的,所以去ushort'不太可能为您赢得任何东西。关于变量缓存:我不确定避免显式访问本地/全局内存是否合法,因为其他工作项可能会修改内存。对于内核中的局部变量:这些变量通常都应该驻留在寄存器中(至少在达到硬件限制之前)。将它们存储在全局内存中会非常慢,并且本地内存有限(不管怎么说,不会比寄存器空间大)。当我在官方文档中读到“计算能力为1.0和1.1的设备每个多处理器有8192个32位寄存器”时,我不知道这是否意味着我可以使用8192*32位寄存器,这意味着两个USHORT(每个16位)可以放在一个32位寄存器中,或者如果我不能在寄存器中存储超过8192个变量,不管它们的大小。在这种情况下,使用ushort实际上对我的目的毫无用处。但我仍然想知道“63”是否对应某些内容。理论上,编译器可以选择两个变量并在一个寄存器中存储两个变量,但不太可能这样做,因为这会使生成的代码更复杂(要处理需要从寄存器中提取的变量,…),这意味着速度较慢。但我帮不了你。