Thrust – 如何使用我的数组/数据 – 模型

我是新手(cuda),我想做一些arrays操作,但我没有在互联网上找到任何类似的例子。

我有两个数组(2d):

a = { {1, 2, 3}, {4} } b = { {5}, {6, 7} } 

我想要推力计算这个数组:

 c = { {1, 2, 3, 5}, {1, 2, 3, 6, 7}, {1, 2, 3, 5}, {1, 2, 3, 6, 7} } 

我知道它在c / c ++中是如何工作的,但不知道怎么说要做到这一点。

这是我的想法,它可能如何工作:

线程1:取一个[0] – >用b展开它。 写给c。

线程2:取一个[1] – >用b展开它。 写给c。

但我不知道该怎么做。 我可以将数组a和b写入1d数组,如:

 thrust::device_vector dev_a; dev_a.push_back(3); // size of first array dev_a.push_back(1); dev_a.push_back(2); dev_a.push_back(3); dev_a.push_back(1); // size of secound array dev_a.push_back(4); thrust::device_vector dev_b; dev_b.push_back(1); // size of first array dev_b.push_back(5); dev_b.push_back(2); // size of secound array dev_b.push_back(6); dev_b.push_back(7); 

和伪function:

 struct expand { __host__ __device__ ?? ?? (const array ai, const array *b) { for bi in b: // each array in the 2d array { c.push_back(bi[0] + ai[0]); // write down the array count for i in ai: // each element in the ai array c.push_back(i); for i in bi: // each element in the bi array c.push_back(i); } } }; 

谁有任何想法?

我猜你在这种操作中不会增加GPU的速度,因为它需要大量的内存访问 – 在GPU上运行缓慢。

但是如果你想要实现这个:

  1. 我想,由于我之前写过的原因,信任不会帮助你使用即用型算法。 这意味着您需要编写自己的内核,但是,您可以将内存管理留给您。

  2. 在CPU内存中创建数组总是更快,并且在准备好后,将整个数组复制到GPU。 (CPU < - > GPU拷贝在长连续数据上更快)

  3. 请记住,GPU并行运行数百个线程。 每个线程都需要知道要读取的内容和写入的位置。

  4. 全局内存操作很慢(300-400个时钟)。 避免线程从全局内存中读取整个数组,以发现它只需要最后几个字节。

所以,我可以看到你编程。

  1. 在CPU内存中使您的arrays1D如下所示:

    float array1 [] = {1,2,3,4}; float array2 [] = {5,6,7}; int arr1offsets [] = {0,2,3,1}; //第一个元素的位置和子arrays对的长度int arr2offsets [] = {0,1,1,2};

  2. 将arrays和偏移复制到GPU并为结果分配内存,并为其抵消。 我想,你必须计算一个联合子arrays的最大长度,并为最坏的情况分配内存。

  3. 运行内核。

  4. 收集结果

内核可能看起来像这样(如果我正确理解你的想法)

 __global__ void kernel(float* arr1, int* arr1offset, float* arr2, int* arr2offset, float* result, int* resultoffset) { int idx = threadIdx.x+ blockDim.x*blockIdx.x; int a1beg = arr1offset[Idx*2]; int a2beg = arr2offset[Idx*2]; int a1len = arr1offset[Idx*2+1]; int a2len = arr2offset[Idx*2+1]; resultoffset[idx*2] = idx*MAX_SUBARRAY_LEN; resultoffset[idx*2+1] = a1len+a2len; for (int k = 0; k < a1len; ++k) result[idx*MAX_SUBARRAY_LEN+k] = arr1[a1beg+k]; for (int k = 0; k < a2len; ++k) result[idx*MAX_SUBARRAY_LEN+a1len+k] = arr2[a2beg+k]; } 

这段代码并不完美,但应该做正确的事情。