关于变量传递问题

有关变量从主函数传递到KERNEL函数发生错误,是什么原因呢?具体看下面的例子吧,抽象来说很难描述清楚。我在kernel中打印传递的变量的值的时候出现了错误。

#include “stdafx.h”
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#define XROW 600
#define XCOL 100
#define Mrand 10
int main(void)
{
double s0=0.1;
double V=(double)malloc(XROWXROWsizeof(double));
int XMatrix=(int)malloc(XROWXCOLsizeof(int));
double VK=(double)malloc(XCOLsizeof(double));
for(int i=0;i<XCOL;i++)
{
VK[i]=0.5;
}
for(int i=0;i<XROW
XCOL;i++)
{
XMatrix[i]=1+rand()%Mrand;
}
for(int i=0;i<XROWXROW;i++)
{
V[i]=0.0;
}
clock_t t1,t2;
t1=clock();
for(int j=0;j<XCOL;j++)
{
for(int i=0;i<XROW;i++)
{
for(int k=0;k<XROW;k++)
{
V[i*XROW+k]=V[i*XROW+k]+XMatrix[i*XCOL+j]XMatrix[kXCOL+j]
(VK[j]-s0);
}
}
}
t2=clock();
for (int i=0;i<10;i++)
{
for(int j=0;j<6;j++)
{
printf("%f ",V[6i+j]);
}
printf(“\n”);
}
printf(“CPU所用的时间为:%d毫秒\n”,(t2-t1));
free(V);
free(XMatrix);
free(VK);
}
我将其中可以加速的部分写成并行的,如下:
global void KernelV11(double dev_V,double dev_VK,int dev_XMatrix,int j,double s0)
{
int tid=threadIdx.x;
int bid=blockIdx.x;
int xIndex=bid
blockDim.x+tid;
printf(“%d\n”,j);
if(xIndex<XROW)
{
if(xIndex==0)
{
dev_V[xIndex]=dev_V[xIndex]+dev_XMatrix[j]dev_XMatrix[xIndexXCOL+j]
(dev_VK[j]-s0);
__syncthreads();
}
else
{
dev_V[xIndex]=dev_V[xIndex]+dev_XMatrix[j]dev_XMatrix[xIndexXCOL+j]
(dev_VK[j]-s0);
__syncthreads();
dev_V[xIndex
XROW]=dev_V[xIndexXROW]+dev_XMatrix[j]dev_XMatrix[xIndexXCOL+j](dev_VK[j]-s0);
__syncthreads();
}
}
__syncthreads();
}
int main(void)
{
clock_t t1,t2;
double V=(double)malloc(XROWXROWsizeof(double));
int XMatrix=(int)malloc(XROWXCOLsizeof(int));
double VK=(double)malloc(XCOLsizeof(double));
for(int i=0;i<XCOL;i++)
{
VK[i]=0.5;
}
for(int i=0;i<XROW
XCOL;i++)
{
XMatrix[i]=1+rand()%Mrand;
}
for(int i=0;i<XROWXROW;i++)
{
V[i]=0.0;
}
double s0=0.1;
double dev_V,dev_VK;
int dev_XMatrix;
cudaMalloc((void
)&dev_V,XROW
XROW
sizeof(double));
cudaMalloc((void**)&dev_XMatrix,XROWXCOLsizeof(int));
cudaMalloc((void**)&dev_VK,XCOLsizeof(double));
t1=clock();
cudaMemcpy(dev_V,V,XROW
XROWsizeof(double),cudaMemcpyHostToDevice);
cudaMemcpy(dev_VK,VK,XCOL
sizeof(double),cudaMemcpyHostToDevice);
cudaMemcpy(dev_XMatrix,XMatrix,XROWXCOLsizeof(int),cudaMemcpyHostToDevice);
for(int j=0;j<XCOL;j++)
{
KernelV11<<<50,300>>>(dev_V,dev_VK,dev_XMatrix,j,s0);
}
cudaMemcpy(V,dev_V,XROWXROWsizeof(double),cudaMemcpyDeviceToHost);

t2=clock();
for (int i=0;i<10;i++)
{
for(int j=0;j<6;j++)
{
printf(“%f “,V[6*i+j]);
}
printf(”\n”);
}
printf(“GPU所用的时间为:%d毫秒\n”,(t2-t1));
cudaFree(dev_V);
cudaFree(dev_VK);
cudaFree(dev_XMatrix);
free(V);
free(XMatrix);
free(VK);
}
但是在kernel中printf(“%d\n”,j);的值全部为99,我认为正确的结果应该是j从0到99才对呀!难道是因为j是变量,要cudaMalloc一下吗?这种情况是不是用zero-copy好一些呢?

大致看了一下您的代码,我认为有如下几点:

1:您每次invoke kernel的时候,j是确定的,但此时,所有的threads (按照您的代码,有50*300个)都会将当前的j打印输出,而他们的j都是一样的。如果您只需要每次invoke kernel输出一次j的值的话,请添加 if xIndex==0 printf 这样的判断,只让0号线程输出即可。你可以看一下有没有解决问题。

2:从参数表传进来的参数可以直接用,和一般的c语言函数参数用法一样。

3:直接用参数即可,无须也不推荐使用zero copy,zero copy可能会变慢。因为zero copy是后台自动维护从host端读取的,但没有缓冲,每次都要读取,频繁读取的话,延迟很要命的。

大致如上,祝您编码愉快。

补充一下,其实就算不改,输出的j也应该是从0到99的。
但是每次kernel启动都会输出50*300=15000行,前面的都应该被刷出屏去了。