OpenCL:最好使用更多寄存器,还是使用位移运算符打包值?

OpenCL: Better to use more registers, or to pack values using bit-shift operators?

在OpenCL中,在GPU上,寄存器压力会降低占用率,所以我们想减少使用的寄存器数量。

在我的程序中,我有大量的值,这些值在编译时是未知的,但通常在 0 到 127 的范围内。我想知道将它们打包成更小数量的值是否更好寄存器,使用位移运算符,而不是为此使用大量寄存器?

例如,也许可以创建一些宏,例如:

#define posToRow( pos ) ( ( pos >> 10 ) & ((1<<10)-1) )
#define posToCol( pos ) ( ( pos ) & ((1<<10)-1) )
#define rowColToPos( row, col ) ( ( row << 10 ) | col )
#define linearIdToPos( linearId, base ) ( rowColToPos( ( linearId / base ), ( linearId % base )  ) )

对此有何想法?有这方面的经验吗? advantages/disadvantages 似乎是:

这可能不会以您想要的方式回答您的问题。

In OpenCL, on GPUs, register pressure will reduce occupation rates, so we want to reduce the number of registers used.

注册压力确实会降低占用率,但这并不意味着它会因此降低性能:它取决于许多其他因素。如果您还没有读过,我强烈建议您阅读 Vasily Volkov 的 Better Performance at Lower Occupancy.

I'm wondering whether it might be better to pack these into a smaller number of registers, using bit-shift operators, rather than use tons of registers for these?

开发人员生活中的一个非常重要的规则是 "don't optimize yet"。即使在高性能代码中,这条规则仍然有效:

  • 首先,让你的代码正常工作。
  • 然后,如果发现性能不理想and/or可以改进,profile就可以了。
  • 然后然后,确定瓶颈并尝试找到解决方案。

总而言之,尝试猜测提前什么可能会或不会造成注册压力是没有意义的。实施、衡量、行动。不要试图预测还不存在并且很可能根本不存在的问题。

也就是说,大多数时候(如果不是总是),在编写高性能代码(实际上甚至是 "standard" 代码)时,知道几个选项中哪个选项最快的唯一方法是实施所有这些并对其进行基准测试。因此,恐怕在您进行此类基准测试之前,您的问题将没有明确的答案。

正如上面提到的大多数答案,请注意不要过度优化您的代码。 您的值通常在 0 到 127 之间,还是这些值始终在此范围内。否则(你没有提到,如果你已经尝试过):你为什么不转向矢量数据(unsigned char16)?