CUDA:如何移动数组元素

时间:2013-02-19 03:58:45

标签: cuda

我需要通过偏移移动1-D数组的每个前k个元素, 其中偏移是单调增加的,即,如果元素i的偏移是offset1 那么元素i + 1具有偏移量offset2,其满足:offset2> = offset1。

我编写了一个在前k个元素中执行的内核:

if (thread_id < k) {

  // compute offset

  if (offset) {
    int temp = a[thread_id];

    __synchthreads();

    a[thread_id + offset] = temp;
  }
}

然而,当测试k = 3时,偏移确实是单调增加的,即 0,1,1。 元素0按预期保持其位置。 但是,元素1不仅会复制到元素2(根据元素1的偏移量),还会复制到元素3中。

也就是说,只有在线程1完成元素1到元素2的复制之后,线程2才会读取元素2并将其存储到temp的副本中。

我做错了什么以及如何解决?

谢谢!

1 个答案:

答案 0 :(得分:3)

您正在做的事情推广到分散操作:

thread   0  1  2  3  4
in  =  { 1, 4, 3, 2, 5}
idx =  { 1, 2, 3, 4, 0}

out[idx] = in[i]

通常,散布不能并行完成,因为线程从其他线程写入的位置读取。在我们的示例中,如果线程2在线程1写入其输出位置后读取其输入位置,则会得到不正确的结果。这是一种竞争条件,需要同步或不合适的存储。

由于这种情况下大型数组的同步是全局同步(CUDA编程模型不支持),因此必须使用不合理的分散。

换句话说,你不能这样做:

temp = in[thread_idx]
global-sync
in[thread_idx + offset] = temp

你必须这样做:

out[i + offset] = in[thread_idx]

其中out未指向与in相同的内存。