使用 CUDA 生成素数时遇到问题

Posted

技术标签:

【中文标题】使用 CUDA 生成素数时遇到问题【英文标题】:Trouble generating prime numbers with CUDA 【发布时间】:2016-09-21 06:05:00 【问题描述】:

我刚刚开始关注 cuda,在阅读了向量和教程 here 之后,我想我会从头开始尝试一些东西来真正让我的腿在我下面。

也就是说,我不知道这里的问题是简单的解决方法还是一大堆问题。

我的代码通俗的英文描述如下:

首先有一个 counterClass,它有成员 num 和 count。通过在 count 等于 num 时设置 count = 0,当我们遍历整数时,这个计数器类将在除以 num 时跟踪余数。

我有 2 个要并行运行的函数。第一个调用 count 将增加我的所有计数器(并行),第二个将检查是否有任何计数器读取 0(并行)如果计数器读取 0,则 num 将 n 均分意味着 n 不是素数。

虽然我希望我的代码只打印素数,但它会打印所有数字...

代码如下:

#include <stdio.h>
#include <stdlib.h>

typedef struct
    int num;
    int count;
 counterClass;

counterClass new_counterClass(counterClass aCounter, int by, int count)
    aCounter.num = by;
    aCounter.count = count%by;
    return aCounter;


__global__ void count(counterClass *Counters)
    int idx = threadIdx.x+blockDim.x*blockIdx.x;
    Counters[idx].count+=1;
    if(Counters[idx].count == Counters[idx].num)
        Counters[idx].count = 0;
    
    __syncthreads();


__global__ void check(counterClass *Counters, bool *result)
    int idx = threadIdx.x+blockDim.x*blockIdx.x;
    if (Counters[idx].count == 0)
        *result = false;
    
    __syncthreads();


int main()
    int tPrimes = 5;    // Total Primes to Find
    int nPrimes = 1;    // Number of Primes Found
    bool  *d_result, h_result=true;
    counterClass *h_counters =(counterClass *)malloc(tPrimes*sizeof(counterClass));
    h_counters[0]=new_counterClass(h_counters[0], 2 , 0);
    counterClass *d_counters;
    int n = 2;
    cudaMalloc((void **)&d_counters, tPrimes*sizeof(counterClass));
    cudaMalloc((void **)&d_result, sizeof(bool));
    cudaMemcpy(d_counters, h_counters, tPrimes*sizeof(counterClass), cudaMemcpyHostToDevice);
    while(nPrimes<tPrimes)
        h_result=true;
        cudaMemcpy(d_result, &h_result, sizeof(bool), cudaMemcpyHostToDevice);
        n+=1;
        count<<<1,nPrimes>>>(d_counters);
        check<<<1,nPrimes>>>(d_counters,d_result);
        cudaMemcpy(&h_result, d_result, sizeof(bool), cudaMemcpyDeviceToHost);
        if(h_result)
            printf("%d\n", n);
            cudaMemcpy(h_counters, d_counters, tPrimes*sizeof(counterClass), cudaMemcpyDeviceToHost);
            h_counters[nPrimes]=new_counterClass(h_counters[nPrimes], n , 0);
            nPrimes += 1;
            cudaMemcpy(d_counters, h_counters, tPrimes*sizeof(counterClass), cudaMemcpyHostToDevice);
        
    

有一些类似的问题CUDA - Sieve of Eratosthenes division into parts 和一些寻求改进代码的人发布的很好的示例,CUDA Primes Generation & Low performance in CUDA prime number generator 但是阅读这些并没有帮助我弄清楚我的代码出了什么问题!

任何关于如何在使用 CUDA 时更有效地调试的建议将不胜感激,如果您能指出 我做错了什么(因为我知道这不是计算机故障),您将获得我的永远尊重。

编辑:

显然这个问题只发生在我身上,所以也许这就是我运行代码的方式......

$ nvcc parraPrimes.cu -o primes
$ ./primes
3
4
5
6

另外按照推荐使用 cuda-memCheck:

$ cuda-memcheck ./primes
========= CUDA-MEMCHECK
3
4
5
6
========= ERROR SUMMARY: 0 errors

dmesg |grep NVRM 的输出如下::

[    3.480443] NVRM: loading NVIDIA UNIX x86_64 Kernel Module  304.131  Sun Nov  8 21:43:33 PST 2015

Nvidia-smi 没有安装在我的系统上。

【问题讨论】:

当我运行你的代码时,它会打印出 3,5,7,11 。您确定没有遇到任何运行时错误吗?我在您的代码中没有看到 API 错误检查。添加它或使用 cuda-memcheck。 这太奇怪了,当我运行我的代码时,它会打印出 3,4,5,6 您的系统配置已损坏。通常 cuda-memcheck 会指出这一点,但在这种情况下,不会。需要进行一些故障排除才能找出原因。下一步是在该系统上运行nvidia-smi,并查看它报告的内容。如果它似乎报告一切正常,那么您将需要尝试正确的 CUDA 错误检查,您可以将其添加到您的代码中,或者运行 CUDA 示例代码之一,例如 vectorAdd。最后,您可能希望在该系统上获得dmesg |grep NVRM 的输出。 如果您的系统上没有安装nvidia-smi,那么您的系统安装(GPU 驱动程序)已损坏。此外,304.131 是一个“相当老的”GPU 驱动程序。您使用的是什么 CUDA 版本?换句话说,nvcc --version 的输出是什么? 好吧,我不得不在这里使用 deb 文件安装 cuda -> developer.nvidia.com/cuda-release-candidate-download 我并不自豪地承认我两次尝试从 .run 文件安装计算机...跨度> 【参考方案1】:

安装 nvidia-cuda-toolkit 不会安装 cuda。

您可以安装 cuda 表单 nvidia's website。 (*使用 .deb)

【讨论】:

没有特别的理由必须使用 .deb。在尝试安装 CUDA 之前,尤其是如果您以前没有安装过,我建议您阅读相关平台的 CUDA 安装指南(即本例中的 linux)。包管理器方法 (.deb) 和运行文件安装程序方法都是可行的,但都必须正确完成。安装指南为每种方法提供了正确的方法和用法。 我使用了安装指南,.run 文件将我的电脑变成了镇纸两次。我尽我所能遵循了安装指南,也许我犯了一个错误,但根据我的经验,我建议任何在 ubuntu 16.04 上安装 CUDA 的人使用 deb 而不是 .run。此外,我读到 .run 文件超出了自动更新的范围,这意味着使用 .deb 安装所需的维护更少。

以上是关于使用 CUDA 生成素数时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

当我仍然有足够的内存时,cuda push::sort 遇到了内存问题

在制作 CUDA 5.0 示例时遇到 Open MPI 相关问题 (Mac OS X ML)

Clojure 中的快速素数生成

浅谈 OpenGL 中相关阻塞问题

CUDA nvcc慢主机代码

遇到 CUDA 非法内存访问