在YOLO采用OpenCL代码时,我遇到了一个性能问题。
该方法只从设备中提取数据,第一次运行缓慢,随后几次调用速度较快。有记录呼叫,时间以微秒为单位:
clEnqueueMapBuffer 144469
memcpy 2
clEnqueueUnmapMemObject 31
clEnqueueMapBuffer 466
memcpy 103
clEnqueueUnmapMemObject 14
clEnqueueMapBuffer 468
memcpy 106
clEnqueueUnmapMemObject 17第一次调用带有1字节副本(其中memcpy需要2微秒)。
内存由代码分配:
if (!x)
x = (float*) calloc(n, sizeof(float));
buf.ptr = x;
cl_int clErr;
buf.org = clCreateBuffer(opencl_context, CL_MEM_READ_WRITE |
CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, buf.len * buf.obs, buf.ptr, &clErr);下一步是提取数据的代码:
#ifdef BENCHMARK
clock_t t;
double time_taken;
t = clock();
#endif
cl_int clErr;
void* map = clEnqueueMapBuffer(opencl_queues[opencl_device_id_t], x_gpu.mem, CL_TRUE, CL_MAP_READ,
0, x_gpu.len * x_gpu.obs, 0, NULL, NULL, &clErr);
#ifdef BENCHMARK
t = clock() - t;
time_taken = ((double)t);
printf("clEnqueueMapBuffer\t%d\n", (int)time_taken);
t = clock();
#endif
if (clErr != CL_SUCCESS)
printf("could not map array to device. error: %s\n", clCheckError(clErr));
memcpy(x, map, (n - x_gpu.off) * x_gpu.obs);
#ifdef BENCHMARK
t = clock() - t;
time_taken = ((double)t);
printf("memcpy\t%d\n", (int)time_taken);
t = clock();
#endif
clErr = clEnqueueUnmapMemObject(opencl_queues[opencl_device_id_t], x_gpu.mem, map, 0, NULL, NULL);
if (clErr != CL_SUCCESS)
printf("could not unmap array from device. error: %s\n", clCheckError(clErr));
#ifdef BENCHMARK
t = clock() - t;
time_taken = ((double)t);
printf("clEnqueueUnmapMemObject\t%d\n", (int)time_taken);
#endif在第一次通话中出现这种延误的原因是什么?如何减少延迟?
发布于 2018-11-12 20:41:34
您的clEnqueueMapBuffer()调用是阻塞的( blocking_map参数的CL_TRUE),这意味着只有在映射操作完成后调用才会返回。如果您的命令队列不是并发的,那么任何以前排队的异步命令(如排队内核)都需要在映射开始之前完成。如果有这样的早期命令,您实际上是在测量它们的完成情况以及内存映射操作。为了避免这种情况,在启动时钟之前添加一个clFinish()调用。(不调用clFinish()可能会稍微有效一些,因此我建议您只为测量目的而保留它。)
https://stackoverflow.com/questions/53267812
复制相似问题