我对制作固定内存有疑问.
现在我正在使用CUDA处理大量数据.
为了减少运行时间,我发现有必要使内存复制和内核启动重叠.
在搜索了一些文本和网页,重叠内存复制和内核启动后,我注意到有必要使用cudaMallocHost分配主机内存,它将主机内存分配给固定内存.
在主机上使用整数或数组类型的情况下,很容易制作固定内存.
像这样...
cudaStream_t* streams = (cudaStream_t*)malloc(MAX_num_stream * sizeof(cudaStream_t));
for(i=0; i<MAX_num_stream; i++)
cudaStreamCreate(&(streams[i]));
cudaMallocHost(&departure, its_size);
for(n=1; ... ; n++){
cudaMemcpyAsync( ... streams[n]);
kernel <<< ... , ... , ... , streams[n] >>> (...);
}
Run Code Online (Sandbox Code Playgroud)
但在我的情况下,我的主机离开内存是由vertor类型设置的.
而且我无法通过使用cudaMallocHost找到将矢量类型主机内存转换为固定内存的方法.
帮助我或提供一些建议来解决这个问题.谢谢你阅读我可怜的英语.谢谢.
我有一些问题.
最近我正在使用CUDA制作一个程序.
在我的程序中,主机上有一个大数据用std :: map(string,vector(int))编程.
通过使用这些数据,一些vector(int)被复制到GPU全局内存并在GPU上处理
处理完成后,会在GPU上生成一些结果,并将这些结果复制到CPU.
这些都是我的课程安排.
但我想减少处理时间.
所以我决定在我的程序中使用cudaMemcpyAsync函数.
在搜索了一些文档和网页后,我意识到要使用cudaMemcpyAsync函数主机内存,其中有数据要复制到GPU全局内存必须分配为固定内存.
但是我的程序正在使用std :: map,所以我无法将这个std :: map数据转换为固定内存.
因此,我没有使用它,而是制作了一个缓冲数组类型的固定内存,这个缓冲区总能处理所有复制矢量的情况.
最后,我的程序像这样工作.
我的程序变得比前一个案例快得多.
但问题(我的好奇心)就是在这一点上.
我尝试以类似的方式制作另一个程序.
该方法比上述方法快约10%.
但我不知道为什么.
我认为cudaMemcpyAsync只能与内核函数重叠.
但我的情况我认为不是.而不是它看起来可以在cudaMemcpyAsync函数之间重叠.
抱歉我的问题很长,但我真的很想知道原因.
有人可以教我或解释一下具体的设施"cudaMemcpyAsync"以及哪些功能可以与"cudaMemcpyAsync"重叠?
我是OpenCL的新手.
从昨天起,我正在尝试使用OpenCL进行并行编程而不是CUDA,这对我来说比较熟悉并且以前经历过.
现在我有NVIDIA GTX 580 GPU,Ubuntu Linux 12.04操作系统和CUDA SDK 4.1(由于CUDA编程之前已安装).
在CUDA SDK文件夹中,已包含一些OpenCL头文件和库.
所以我刚从NVIDIA的开发者专区下载了OpenCL示例.(这是链接!https://developer.nvidia.com/opencl)
而且我试图自己编译一些例子,但我不能.
我使用-II添加了头文件的路径来制作Makefile,但我不知道如何添加库路径以及OpenCL库的名称是什么.
我在谷歌搜索但有人说文件名为libOpenCL.so,但我只有OpenCL.lib.
有人可以帮助我吗?
我写了这样的示例代码.
int ** d_ptr;
cudaMalloc( (void**)&d_ptr, sizeof(int*)*N );
int* tmp_ptr[N];
for(int i=0; i<N; i++)
cudaMalloc( (void**)&tmp_ptr[i], sizeof(int)*SIZE );
cudaMemcpy(d_ptr, tmp_ptr, sizeof(tmp_ptr), cudaMemcpyHostToDevice);
Run Code Online (Sandbox Code Playgroud)
这段代码运行良好但在内核启动后我无法收到结果.
int* Mtx_on_GPU[N];
cudaMemcpy(Mtx_on_GPU, d_ptr, sizeof(int)*N*SIZE, cudaMemcpyDeviceToHost);
Run Code Online (Sandbox Code Playgroud)
此时,发生段错误错误.但我不知道我错了什么.
int* Mtx_on_GPU[N];
for(int i=0; i<N; i++)
cudaMemcpy(Mtx_on_GPU[i], d_ptr[i], sizeof(int)*SIZE, cudaMemcpyDeviceToHost);
Run Code Online (Sandbox Code Playgroud)
此代码也有相同的错误.
我认为我的代码肯定会有一些错误,但我无法在白天找到它.
给我一些建议.
我试图自己解决这个问题,但我不能.所以我想得到你的建议.
我正在写这样的内核代码.VGA是GTX 580.
xxxx <<< blockNum, threadNum, SharedSize >>> (... threadNum ...)
(note. SharedSize is set 2*threadNum)
__global__ void xxxx(..., int threadNum, ...)
{
extern __shared__ int shared[];
int* sub_arr = &shared[0];
int* sub_numCounting = &shared[threadNum];
...
}
Run Code Online (Sandbox Code Playgroud)
我的程序每个块创建大约1085个块和1024个线程.
(我正在尝试处理巨大的数组)
所以每个块的共享内存大小是8192(1024*2*4)字节,对吧?
我想通过使用cudaDeviceProp,我可以在GTX 580上的每个块的共享内存中使用最大49152bytes.
而且我知道GTX 580有16个处理器,可以在处理器上实现线程块.
但我的程序出错.(8192bytes <49152bytes)
我在内核中使用"printf"来查看是否运行良好但是几个块不运行.(虽然我创建了1085个块,但实际上只有50~100个块可以运行.)
我想知道在同一个处理器上运行的块是否共享相同的共享内存地址.(如果没有,为共享内存分配其他内存?)
我无法理解每个块的共享内存的最大大小意味着什么.
给我建议.
我现在只需要显示矩阵乘法的中间进度.
for(unsigned int col=0; col<mtxSize; col++) {
unsigned tmp = 0;
for(unsigned int row=0; row<mtxSize; row++) {
for(unsigned int idx=0; idx<mtxSize; idx++) {
tmp += h_A[col*mtxSize+idx] * h_B[idx*mtxSize+row];
}
h_Rs[col*mtxSize+row] = tmp;
tmp = 0;
int rate_tmp = (col*mtxSize + (row+1))*100;
// Maybe like this...
fprintf(stdout, "Progress : %d.%d %%\r", rate_tmp/actMtxSize, rate_tmp%actMtxSize);
fflush(stdout);
}
}
Run Code Online (Sandbox Code Playgroud)
在主机代码(使用CPU)的情况下,它很容易,因为它顺序处理,所以我们可以很容易地检查.
但是在GPU并行处理的情况下,我该怎么办?
内核运行后,在完成内核执行之前不会返回.
所以我无法在内核执行期间检查中间数据.
我想我需要使用异步内核调用,但我不太清楚.
即使使用了异步内核调用,要将所有数据看到处理器上的几个块,我是否必须编写atomicAdd()(换句话说,全局内存访问)函数,其中包括一些开销?
给我一些建议或提示.
我想知道CUDA的情况.