使用 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 遇到了内存问题