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

标签 c arrays cuda thrust code-complexity

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

我有以下两个数组(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: 取 a[0] -> 用 b 展开它。 将其写入c。

主题 2: 取 a[1] -> 用 b 展开它。 将其写入c。

但我不知道该怎么做。我可以将数组 a 和 b 写入一维数组,如下所示:

thrust::device_vector<int> 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<int> 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); 

以及伪函数:

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 的速度不会得到任何提升,因为它需要大量 oo 内存访问 - GPU 上的操作很慢。

但是如果你无论如何想实现这个:

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

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

  3. 请记住,GPU 并行运行数百个线程。每个线程都需要知道要读什么以及写在哪里。

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

所以,正如我所看到的,你正在编程。

  1. 使 CPU 内存中的一维数组如下所示:

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

  2. 将数组和偏移量复制到 GPU 并为结果及其偏移量分配内存。我想,您必须计算一个 union 子数组的最大长度,并为最坏的情况分配内存。

  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];
}

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

关于c - Thrust - 如何使用我的数组/数据 - 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14204562/

相关文章:

c - 需要将参数传递给 dev_err 宏

Java检查数组是否已满,并将不同数组的一部分复制到另一个数组

java - Codility 中的 TapeEquilibrium 问题

memory - 二维 block 的 CUDA 合并访问

c++ - 如何检查编译库的 CUDA 计算兼容性?

C语言 : string concatenation on string pointer

比较和替换 C 中的重音/特殊字符

c - GreenHills 编译器调用图

java - Google gson.toJson(List) 以字符串而不是数组形式返回响应

c++ - CUDA:使用 tex2D() 的问题