我是CUDA的新手,试图掌握基本知识,所以如果我要求或说出的内容听起来过于简单,我表示歉意。我用C编写了一些序列码,用于生成一个随机数组,然后在该数组中找到最大值。将C程序转换为CUDA(最大程度减少)
#include <stdio.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#define num 100000
int *arr,max = -1;
int getRand() {
double r1=rand()/(double)RAND_MAX; // Generates value between 0 & 1
return (r1 * num) + 1;
}
void generateRandom(int M) {
int i;
for(i=0;i<M;i++) {
arr[i] = getRand();
}
}
void getMax(int M) {
int i;
for(i=0;i<M;i++) {
if(arr[i] > max)
max = arr[i];
}
}
int main(int argc, char *argv[]){
if (argc == 2) {
int M;
/* initialize random seed: */
srand (time(NULL));
M = atoi(argv[1]);
//int arr[M];
arr = (int*)calloc(M,sizeof(int));;
//printf("M = %d MAX = %d\n", M, RAND_MAX);
generateRandom(M);
getMax(M);
printf("Max value: %d",max);
}
else
printf("Invalid arguments.");
return 0;
}
我现在试图将此代码转换为简单的CUDA程序。我试着让generateRandom函数作为内核运行,但是我遇到了内存管理的问题。
#include <stdio.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <cuda.h>
#define num 100000
int *arr,max = -1;
int getRand() {
double r1=rand()/(double)RAND_MAX; // Generates value between 0 & 1
return (r1 * num) + 1;
}
void generateRandom(int M) {
int i;
for(i=0;i<M;i++) {
arr[i] = getRand();
}
}
__global__ void getMax(int M) {
int i;
for(i=0;i<M;i++) {
if(arr[i] > max)
max = arr[i];
}
}
int main(int argc, char *argv[]){
if (argc == 2) {
int M;
/* initialize random seed: */
srand (time(NULL));
M = atoi(argv[1]);
//int arr[M];
arr = (int*)calloc(M,sizeof(int));
//printf("M = %d MAX = %d\n", M, RAND_MAX);
generateRandom(M);
getMax<<<1,1>>>(M);
printf("Max value: %d",max);
}
else
printf("Invalid arguments.");
return 0;
}
该代码导致以下错误。
cudabasic.cu(23): warning: a host variable "arr" cannot be directly read in >a device function
cudabasic.cu(23): warning: a host variable "max" cannot be directly read in >a device function
cudabasic.cu(24): warning: a host variable "arr" cannot be directly read in >a device function
cudabasic.cu(24): warning: a host variable "max" cannot be directly written >in a device function
我一派错误和发现该问题是,我是路过的全局变量的内核,因此该设备wasnt能够读取它。遵循在线建议,我试图通过使用指针而不是传递实际变量来解决此问题,但我仍然遇到错误。
#include <stdio.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <cuda.h>
#define num 100000
int *arr,max = -1;
int getRand() {
double r1=rand()/(double)RAND_MAX; // Generates value between 0 & 1
return (r1 * num) + 1;
}
void generateRandom(int M) {
int i;
for(i=0;i<M;i++) {
arr[i] = getRand();
}
}
__global__ void getMax(int M, int *dArr, int *dMax) {
int i = threadIdx.x;
int a = dArr[i];
for(i=0;i<M;i++) {
if(a > dMax)
dMax = a;
}
}
int main(int argc, char *argv[]){
if (argc == 2) {
int M;
/* initialize random seed: */
srand (time(NULL));
M = atoi(argv[1]);
//int arr[M];
arr = (int*)calloc(M,sizeof(int));
devArr = (int*)cudaMalloc(M,sizeof(int));
//printf("M = %d MAX = %d\n", M, RAND_MAX);
generateRandom(M);
getMax<<<1,1>>>(M, arr, max);
printf("Max value: %d",max);
}
else
printf("Invalid arguments.");
return 0;
}
cudabasic.cu(24): error: operand types are incompatible ("int" and "int *")
cudabasic.cu(25): error: a value of type "int" cannot be assigned to an >entity of type "int *"
有人能指出我在如何最好地去这样做这个正确的方向?
我是CUDA新手,想要掌握基本知识,所以如果我要求或说出的内容听起来过于简单,我表示歉意。
嗨,谢谢你的解释,他们一直很有帮助。我之所以使用threadIdx.x的原因是因为我现在想让这个代码使用多线程(我想我已经比自己领先了一点)。你能告诉我这也可以做到吗? 另外我也试过看你链接到的示例代码,但我可以找出在哪里查看代码。页面列表减少 - CUDA并行减少和版本支持,但我不明白如何查看实际的代码。 – Lesha
我已更新我的原始文章,包括我的第一次尝试,但不幸的是它非常成功。我会看看我能否解决它,但如果你能提供一些非常有用的建议。 – Lesha
对您的问题进行批发更改会让我的答案令未来的读者感到困惑。我建议问一个新问题。 SO不打算成聊天会话或运行对话框。你的“新”代码仍然有明显的缺陷。例如,您将启动每个线程64个块。在这种情况下,'threadIdx.x'将*仍然*总是为零。试图以这种方式组合CUDA知识是非常乏味的。为什么不使用我链接的一些材料?如果你这样做,你会理解为什么'threadIdx.x'将*仍然*在你的新代码中始终为零。 –