Nvidia OpenCL挂起阻塞缓冲区访问

时间:2015-06-26 10:53:13

标签: opencl gpu gpgpu nvidia

我有一个OpenCL程序,它将一堆值复制到输入缓冲区,处理这些值,然后将结果复制回来。

// map input data buffer, has CL_MEM_ALLOC_HOST_PTR
cl_float* data = clEnqueueMapBuffer(queue, data_buffer, CL_TRUE, CL_MAP_WRITE, 0, data_size, 0, NULL, NULL, NULL);

// set input values
for(size_t i = 0; i < n; ++i)
    data[i] = values[i];

// unmap input buffer
clEnqueueUnmapMemObject(queue, data_buffer, data, 0, NULL, NULL);

// run kernels
...

// map results buffer, has CL_MEM_ALLOC_HOST_PTR
cl_float* results = clEnqueueMapBuffer(queue, results_buffer, CL_TRUE, CL_MAP_READ, 0, results_size, 0, NULL, NULL, NULL);

// processing
...

// unmap results buffer
clEnqueueUnmapMemObject(queue, results_buffer, results, 0, NULL, NULL);

(在实际代码中,我检查错误等。)

这在AMD和英特尔架构(CPU和GPU)上都很有用。在Nvidia GPU上,代码非常慢。一个通常需要10秒钟运行的程序(5秒主机,5秒设备)将在Nvidia卡上运行超过2.5分钟。

但是,我发现这不是一个简单的优化问题或零拷贝速度差异。使用分析器,我看到程序的主机时间是5秒,与正常情况一样。使用OpenCL分析事件,我发现设备时间也是5秒,与正常情况一样!

所以我使用poor mans' profiler技巧来确定程序在Nvidia GPU上花费的时间。并且它表明该程序只是在clEnqueueMapBuffer两个调用上等待。我发现这在第一个实例中特别难以理解,因为那时队列是空的。

我再说一遍,我已经分析了每个map / unmap和内核调用,并且额外的时间没有出现在那里,所以它没有花在设备上,也没有花在主机上。我可以从堆栈配置文件中看到它正在等待信号量。任何人都知道造成这种情况的原因是什么?

0 个答案:

没有答案