【问题标题】:Find the index of an element in an array with cuda c++使用cuda c ++查找数组中元素的索引
【发布时间】:2021-08-29 16:01:41
【问题描述】:

我是 cuda 新手。

我有两个数组:

  int* AA = new int[5]{1,2,3,4,5};
  int* BB = new int[5]{ 2,2,2,4,4 };

我想找到 AA 中每个元素的索引,它等于 BB 中的每个元素,在这种情况下是

{1,1,1,3,3}

这是我的代码:

__global__ void findIndex(int* A, int* B, int* C)
{
    int i = threadIdx.x;


    for (int j = 0; j < 5; j++)
    {
        if (B[i] == A[j])
        {
            C[i] = j;

        }
    }
}


int main() {

    int* AA = new int[5]{1,2,3,4,5};
    int* BB = new int[5]{ 2,2,2,4,4 };
    int* CC = new int[5]{ 0,0,0,0,0 };

    int(*ppA), (*ppB), (*ppC);

    cudaMalloc((void**)&ppA, (5) * sizeof(int));
    cudaMalloc((void**)&ppB, (5) * sizeof(int));
    cudaMalloc((void**)&ppC, (5) * sizeof(int));

    cudaMemcpy(ppA, AA, 5 * sizeof(int), cudaMemcpyHostToDevice);
    cudaMemcpy(ppB, BB, 5 * sizeof(int), cudaMemcpyHostToDevice);
    cudaMemcpy(ppC, CC, 5 * sizeof(int), cudaMemcpyHostToDevice);

    int numBlocks = 1;
    dim3 threadsPerBlock(5);
    findIndex << <numBlocks, threadsPerBlock >> > (ppA, ppB, ppC);


    cudaMemcpy(CC, ppC, 5 * sizeof(int), cudaMemcpyDeviceToHost);
    for (int m = 0; m < 5; m++) {
        printf("%d ", CC[m]);
    }
}

我的输出是:

{1,2,3,0,0}

谁能帮忙?

【问题讨论】:

  • 使用thurst之类的库,写一些代码。多种可能性
  • 感谢您的回答,但由于某些原因,我需要自己写...
  • 谢谢罗伯特,我不是在写作业!!:)) 这是我的全部问题:我有两个不同大小的数组,需要找到第一个数组中每个元素的索引第二个数组,我写了一些代码,但它没有得到我想要的结果......
  • 如果目的是获取索引,为什么你的代码存储它找到的每个匹配的
  • 当有多个索引值为 4 时会发生什么?不可能发生?取回任何一个结果?取回结果列表?我建议,您先尝试编写一个正常的函数,它可以正确完成任务,然后尝试将其移植到 Cuda。

标签: c++ cuda


【解决方案1】:

最简单的非稳定单 GPU 解决方案是使用原子,如下所示:

__global__ void find(int * arr,int * counter, int * result)
{
    int id = blockIdx.x*blockDim.x+threadIdx.x;
    if(arr[id] == 4)
    {
        int ctr = atomicAdd(counter,1);
        result[ctr] = id;
    }
}

通过这种方式,您可以在“结果”数组中获得一个结果数组,如果想要的数字很少,它不会减慢很多(就像整个源数组中只有少数)。不过,这不是多 GPU 系统的最佳方式。需要 gpus 之间的主机端协调,除非使用最新工具包中的特殊 CUDA 功能(用于系统级原子)。

如果 4 的数量导致“密集”arr 数组或者如果您有多个 GPU,那么您应该寻找其他解决方案,例如流压缩。首先选择包含 4 的单元格作为掩码。然后进行压实。一些 Nvidia 博客或教程有此算法。

对于“原子”解决方案(尤其是“共享”内存原子),Maxwell(及更高版本)架构比 Kepler 要好得多,以防万一您仍然使用 Kepler。由于无法知道原子操作的顺序,因此使用原子也不能完全重现。 大多数时候你会得到一个不同顺序的结果数组。但是流压缩保留了结果顺序。这可能使您免于在其之上编写排序算法(如双调排序、剪切排序等)。

【讨论】:

  • 我是否必须#include 特定的标头才能使用 atomicAdd?因为我得到了未定义的错误...
猜你喜欢
  • 2016-06-09
  • 2021-06-20
  • 2013-08-26
  • 2015-08-19
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
  • 2019-01-12
  • 2013-07-19
相关资源
最近更新 更多