CUDA:将不同线程中的向量堆栈到一维向量

CUDA: Stack vector in different thread to a 1d vector

我在 CUDA 中为每个线程都有一个推力向量,我想按顺序堆叠向量(线程 0 中的向量,线程 1 中的向量,......和线程 n 中的向量)以创建一维向量并发送回 CPU。有没有好的方法来做到这一点?任何帮助表示赞赏。谢谢。

将来自多个线程的项目存储到单个向量中的最高效方法是 thread-interleaved。假设 4 个线程 (t0-t3) 中的每一个都有 4 个元素要存储 (e0-e3)。最有效的最终存储模式将是:

t0e0 t1e0 t2e0 t3e0 t0e1 t1e1 t2e1 t3e1 t0e2 t1e2 t2e2 t3e2 t0e3 t1e3 t2e3 t3e3

执行此操作的代码如下所示:

#include <thrust/device_vector.h>
const int nt = 4;
const int ne = 4;
template <typename T>
__global__ void k(T *d){

  T e0 = threadIdx.x+10;
  T e1 = threadIdx.x+20;
  T e2 = threadIdx.x+30;
  T e3 = threadIdx.x+40;
  d[threadIdx.x]      = e0;
  d[threadIdx.x+nt]   = e1;
  d[threadIdx.x+2*nt] = e2;
  d[threadIdx.x+3*nt] = e3;
}

int main(){

  thrust::device_vector<int> d(ne*nt);
  k<<<1,nt>>>(thrust::raw_pointer_cast(d.data()));
}

在你的问题中,你似乎想要这样的顺序:

t0e0 t0e1 t0e2 t0e3 t1e0 t1e1 t1e2 t1e3 t2e0 t2e1 t2e2 t2e3 t3e0 t3e1 t3e2 t3e3

该存储模式通常效率较低,但您可以这样实现:

#include <thrust/device_vector.h>
const int nt = 4;
const int ne = 4;
template <typename T>
__global__ void k(T *d){

  T e0 = threadIdx.x+10;
  T e1 = threadIdx.x+20;
  T e2 = threadIdx.x+30;
  T e3 = threadIdx.x+40;
  d[threadIdx.x*nt]    = e0;
  d[threadIdx.x*nt+1]  = e1;
  d[threadIdx.x*nt+2]  = e2;
  d[threadIdx.x*nt+3]  = e3;
}

int main(){

  thrust::device_vector<int> d(ne*nt);
  k<<<1,nt>>>(thrust::raw_pointer_cast(d.data()));
}

这两种情况下的存储效率差异是未合并和合并行为之间的差异,cuda SO 标签上的许多问题都涵盖了这一点,例如 this one.