CUDA中每个块的数据 - 它是否在一个事务中广播?

时间:2012-09-10 19:23:07

标签: cuda gpgpu nvidia

我有一个按块的数据数组。 我有一个cuda Grid中的N个块和一个大小为N的常量数据块“block_data []”。

因此,给定块“X”中的所有线程只访问block_data [X]一次,并使用该值执行某些操作。

我的问题是:这个广播方案有效吗? 如果没有,我应该采取什么方法?

评论后编辑:我唯一的问题是常量内存是有限的大小,因为我可以拥有超过64K的块。这意味着超过64KB

问候

2 个答案:

答案 0 :(得分:1)

如果要更改block_data[N]数组中的值,请更好地使用共享内存__shared__的概念。如果您不更改block_data[N]的值,请使用__const__或使用缓存的概念。通过使用L2缓存,您可以获得1536KB的内存(开普勒)。

答案 1 :(得分:1)

如果您只使用正常的全局内存访问,那么事务处理效率相当低,尽管取决于内核的工作量,影响可能非常小。

我假设sizeof(block_data)是一个字节(从您的问题推断“......可能有超过64K的块。这意味着超过64KB”)。

  • 如果操作缓存在L1中,那么您将获取所需信息的一位128字节(sizeof(block_data)),如果块中的其他warp请求相同的数据,那么它们应该从L1获取。负载的效率是1/128,但你应该只为该块支付一次。
  • 如果操作未在L1中缓存(例如,将“-dlcm = cg”传递给汇编程序),则将获取32个字节。效率为1/32,但每次经纱都要支付一次。
  • 加载数据后,它将广播到warp中的所有线程。

另一种方法是将数据标记为const __restrict__,它向编译器指示数据是a)只读和b)没有任何其他指针别名。由于编译器可以检测到访问是统一的,因此它可以优化访问以使用其中一个只读缓存(例如,常量缓存,或者,在计算能力> = 3.5,只读数据缓存,即纹理缓存)。 / p>