首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >第一次clEnqueueMapBuffer调用需要很长时间

第一次clEnqueueMapBuffer调用需要很长时间
EN

Stack Overflow用户
提问于 2018-11-12 18:11:10
回答 1查看 242关注 0票数 2

在YOLO采用OpenCL代码时,我遇到了一个性能问题。

该方法只从设备中提取数据,第一次运行缓慢,随后几次调用速度较快。有记录呼叫,时间以微秒为单位:

代码语言:javascript
复制
clEnqueueMapBuffer      144469
memcpy  2
clEnqueueUnmapMemObject 31
clEnqueueMapBuffer      466
memcpy  103
clEnqueueUnmapMemObject 14
clEnqueueMapBuffer      468
memcpy  106
clEnqueueUnmapMemObject 17

第一次调用带有1字节副本(其中memcpy需要2微秒)。

内存由代码分配:

代码语言:javascript
复制
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);

下一步是提取数据的代码:

代码语言:javascript
复制
#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

在第一次通话中出现这种延误的原因是什么?如何减少延迟?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-12 20:41:34

您的clEnqueueMapBuffer()调用是阻塞的( blocking_map参数的CL_TRUE),这意味着只有在映射操作完成后调用才会返回。如果您的命令队列不是并发的,那么任何以前排队的异步命令(如排队内核)都需要在映射开始之前完成。如果有这样的早期命令,您实际上是在测量它们的完成情况以及内存映射操作。为了避免这种情况,在启动时钟之前添加一个clFinish()调用。(不调用clFinish()可能会稍微有效一些,因此我建议您只为测量目的而保留它。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53267812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档