想学习一下流的用法,写了一个很简单的程序,但运行错误

版主,你好,我看了SDK里的简单流使用后,就想学习一下怎么使用流,就写了下面这个简单的程序,但发现运行有错误,不知道哪里有问题,请版主指教一下,下面代码已经作了简单的注释了。

#include <cuda_runtime.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef unsigned int uint;
typedef unsigned char uchar;

global void init_array(floatin,float factor,uint num)
{
uint tx=blockIdx.x
blockDim.x+threadIdx.x;

if(tx<num)     //num为数组大小,factor是一个常数,数组中每个元素的值加个一个factor
	in[tx]+=factor;

}

int main ()
{
float factor=1.5f; // 加一个常数
uint num=4096; //多少个数据
float h_Data =0; //内存指针
float
gpuresult=0; //结果指针
float *d_Data=0; //显存指针
uint bytes=sizeof(float)*num; //多少字节

int nstreams=4;
cudaStream_t *streams=(cudaStream_t*)malloc(nstreams*sizeof(cudaStream_t));
for(int i=0;i<nstreams;i++)        //创建流
	cudaStreamCreate(&(streams[i]));

cudaMallocHost((void**)gpuresult,bytes);  //开辟内存
cudaMallocHost((void**)h_Data,bytes);    //开辟内存
for(uint i=0;i<num;i++)
{
	h_Data[i]=(float)i;       //初始化数据
}

cudaMalloc((void **) &d_Data,bytes);   //开辟显存
for(int i=0;i<nstreams;i++)          //拷贝数据过显存
	cudaMemcpyAsync(d_Data+i*num/nstreams,h_Data+i*num/nstreams,bytes/nstreams,cudaMemcpyHostToDevice,streams[i]);

dim3 Block(512,1,1);
dim3 Grid(num/(nstreams*Block.x),1,1);     

for(int i=0;i<nstreams;i++)
	init_array<<<Grid,Block,0, streams[i]>>>(d_Data+i*num/nstreams,factor,num);   //执行

for(int i=0;i<nstreams;i++)             
	cudaMemcpyAsync(gpuresult+i*num/nstreams,d_Data+i*num/nstreams,bytes/nstreams,cudaMemcpyDeviceToHost,streams[i]);     //拷贝数据回内存

for(uint i=0;i<10;i++)
	printf("%f\n",gpuresult[i]);      //输部分数据出来观察结果对不对。

for (int i = 0; i < nstreams; i++)

cudaStreamDestroy(streams[i]); //销毁流

cudaFreeHost(gpuresult);
cudaFree(d_Data);
cudaFreeHost(h_Data);

return 0;

}

楼主您好,

你没有等待异步传输结束呢。
请您在您的printf()之前,加入cudaDeviceSynchronize(),等待传输结束。

以及,这是您的最明显的错误,本回复不代表你没有其他错误。

感谢周末来访。

//cudaMallocHost((void**)gpuresult,bytes); //开辟内存
//cudaMallocHost((void**)h_Data,bytes); //开辟内存
gpuresult=(float*)malloc(bytes);
h_Data=(float*)malloc(bytes);

用malloc分配内存就没问题了。
结果是1.5 一直到10.5 你运行下看对不对。

使用普通的malloc替代cudaMallocHost,

将降级cudaMemcpyAsync为cudaMemcpy, 虽然cudaMemcpy无需等待,但也失去了传输和计算并行的可能。

请楼主您考虑好这一点。

malloc,用这种是没问题的,算出来的结果是对的。就是用这种cudaMallocHost时不行而已。

但此时就失去异步copy的能力了,正如4#玫瑰斑竹所言~

加入这个cudaDeviceSynchronize()后,还不行,出现的问题还是:“出现一个问题,导致程序停止正常工作,请关闭该程序“。我不使用流时,用普通的malloc替代cudaMallocHost,程序是可以运行的,结果也是对的。

那证明您还有更多BUG…

已经为您找到另外1处BUG:
请您修改分配代码:
cudaMallocHost((void**)gpuresult,bytes);
cudaMallocHost((void**)h_Data,bytes);

为:
cudaMallocHost((void **)&gpuresult, bytes);
cudaMallocHost((void **)&h_Data, bytes)l
也就是把你原来的变量名分别加上2个&号。

请您立刻修复此BUG.

呵呵,谢谢版主了,原来漏了&,现在结果是正确的了。但是为什么VS编译器没有提示我cudaMallocHost这个语法弄错了。

恩,知道,现在玫瑰幻想版主已经帮我找到了BUG,现在运行结果没问题了。谢谢版主了。

因为你有强制转换,编译器看到你从void *强制转换到了void **, 它以为这是你故意的行为。因此不会提示什么。

感谢来访。

哦,原来如此,谢谢热心版主了。