【发布时间】: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 文件安装计算机...跨度>
标签: parallel-processing cuda primes