【问题标题】:OpenCL: how to copy contiguous chunk of global mem to private mem?OpenCL:如何将连续的全局内存块复制到私有内存?
【发布时间】:2014-01-14 09:12:14
【问题描述】:

如何将连续的常量全局内存块复制到(一块连续的)私有内存?我需要 memcpy 之类的东西,然后用于在不同的 OpenCL 地址空间之间复制字节。我知道块的大小和数据连续存储在全局和本地/私有内存中,所以,总的来说,这应该是可能的,对吧?

在我的具体问题中,我有一个结构类型的常量全局数组,其中包含 int、float 甚至另一种结构类型。为了防止将结构的每个成员与全局内存分开(这很慢),我想在私有内存中拥有一个完整数组元素的副本。不幸的是,像 privatestruct = globalstruct[i] 这样的操作不会导致完整结构的深层复制。

当然,我不是第一个提出这个或类似问题的人,所以 stackoverflow 上有几个线程讨论相关问题。但是,实际上所有答案都建议使用 async_work_group_copy 这不能是通用答案,因为它仅被定义为干净的内置数据类型,而不是混合结构、结构结构或任何(例如按位)用户定义的内存解释.无论如何,它是为本地内存准备的。

非常感谢您的任何建议!

【问题讨论】:

  • 我在设计中使用了结构体。访问慢没问题。这完全取决于您如何访问结构,以及是否以合并的方式进行访问。也许您使用的结构不是最有效的模式。我建议您使用 async_work_group_copy() 但将指针转换为通用类型。然后,如果您知道结构的大小,那么以后使用它(在另一次转换之后)应该没有问题。
  • 谢谢!我会试试这个......结构的目的是让线程所需的所有输入数据都连续位于内存中,所以我没有太多可以优化的地方

标签: memory struct opencl memcpy


【解决方案1】:

1) 使您的结构大小为 4 字节的倍数。例如,如果它是 125 字节长,那么您可以添加一个 3 字节长的 char3 以获得 128 字节的结构块。

2) 将结构、最大或多个 4 字节元素重新排序为“头”,将较小/非多个元素重新排序为“尾”。这将使您的结构需要更少的内存访问操作。

3) 正如 DarkZeros 提到的,您可以尝试使用 _work_group_copy 获取结构(如果结构太大,则转换为 long16 或类似),然后将值按元素传送到私有内存.为此有许多缓存行,因此从本地复制到私有将足够快。 (不要忘记在转换之前/之后同步它们)

4) 将小变量打包成更大的变量,直到它填满一个缓存通道,这样在高速缓存使用率高时就不会浪费通道的带宽。

但是,如果您要将“单个”结构复制到线程组的“所有核心”,则可以按元素复制,因为一些较新的 GPU 具有广播技术,在这种情况下可能是最快的。请指出未来的任何加速(如果算法恰好有),作为乘数。

5) 有时,繁重的分支会清除性能并隐藏那些内存延迟以进行基准测试(当然,这是一种糟糕的方式)。

【讨论】:

  • 非常感谢!我会试试这个,希望能很快回来并提供一些性能数据
  • @elorenz:这有帮助吗?
猜你喜欢
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
  • 1970-01-01
相关资源
最近更新 更多