代码之家  ›  专栏  ›  技术社区  ›  Dae

在本地内存中只分配一次常量内存变量,并在其工作组中共享

  •  1
  • Dae  · 技术社区  · 7 年前

    我有一个OpenCL应用程序,其内核都共享两大块常量内存。其中一个用于生成密码,另一个用于测试密码。

    这两个子程序单独运行时速度非常快,但当我一个接一个地运行这两个子程序时(我的性能只有通常的四分之一),速度会减慢到停止。

    我认为这是因为测试密码的子例程有一个巨大的(10k)AES解密查找表,而这不是在同一工作组中同时运行的多个内核之间共享的。

    我知道它没有共享,因为AES查找表分配为 __local

    我试着改变 __本地 分配/初始化到 __constant 变量,一个指向库的常量内存的指针,但这会得到 性能降低10倍 .

    1 回复  |  直到 7 年前
        1
  •  2
  •   JohnDuck    7 年前

    __constant 内存按定义是由所有工作组共享的,因此我希望在任何合理的实现中,它只在计算设备上为每个内核分配一次。

    另一方面,如果你有两个独立的内核,你正在背靠背排队,我想不出一个合理的方法来保证 __常量 内存在设备上共享或保留。如果您希望合理地确保将某个缓冲区复制到计算设备一次,以供两个子例程使用,那么这些子例程应该是同一内核的一部分。

    一般来说,性能将取决于底层硬件&OpenCL实现,并且它不会在不同的设备之间进行移植。您应该看看是否有针对您正在使用的硬件的OpenCL性能指南。

    至于 为什么? __常量 内存可能比 __local 内存,这同样取决于硬件以及OpenCL实现如何将地址空间映射到硬件上的内存位置。你的错误是假设 __常量 内存将更快,因为它根据定义是一致的。 哪里 设备上的内存将决定其速度(即每个工作组缓冲区的速度快,而设备上所有工作组共享的缓冲区的速度慢),而OpenCL地址空间只是OpenCL实现如何/在何处分配内存的一个因素。(尺寸也很重要,可以想象 __常量 内存足够小,每个工作组的内存将“提升”到更快的速度,但这完全取决于实现。)

    如果 __本地 正如您所说,内存更快,那么您可以考虑将您的工作拆分为工作组大小的块,并只将工作组所需的表部分传递给 __本地 缓冲区作为内核参数。