我是 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 上的操作很慢。
但是如果你无论如何想实现这个:
我想,由于我之前写过的原因,信任不会帮助您使用现成的算法。这意味着您需要编写自己的内核,但是,您可以将内存管理留给这样。
在 CPU 内存中创建数组总是更快,并在准备好后将整个数组复制到 GPU。 (CPU <->GPU 复制在长连续数据上速度更快)
请记住,GPU 并行运行数百个线程。每个线程都需要知道要读什么以及写在哪里。
全局内存操作很慢(300-400 个时钟)。避免线程从全局内存读取整个数组来发现它只需要最后几个字节。
所以,正如我所看到的,你正在编程。
使 CPU 内存中的一维数组如下所示:
float 组1[] = { 1, 2, 3, 4}; float 组2[] = { 5, 6, 7}; int arr1offsets[] = {0, 2, 3, 1};//第一个元素的位置和子数组对的长度 int arr2offsets[] = {0, 1, 1, 2};
将数组和偏移量复制到 GPU 并为结果及其偏移量分配内存。我想,您必须计算一个 union 子数组的最大长度,并为最坏的情况分配内存。
运行内核。
收集结果
内核可能看起来像这样(如果我正确理解你的想法)
__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/