新手学习OPENCL,对资源上下载感觉很困惑,求[名词2]指教

  • 0 replies
  • 2465 views
 本帖最后由 zhengjianhong 于 2018-3-12 11:40 编辑

先上我的显卡GPU-Z截图[img=110,0]http://bbs.gpuworld.cn/forum.php?mod=image&aid=1595&size=300x300&key=88e04d27e68950ad&nocache=yes&type=fixnone[/img]
使用两种方式初始化设备缓存对象
1.按照OPENCL1.2的API说明文档以及在网上查找的资料,在调用clCreateBuffer创建缓存对象时,使用CL_MEM_ALLOC_HOST_PTR标志,然后使用clEnqueueMapBuffer映射缓存对象,再用内存Buffer来初始化缓存对象,然后在解映射。
代码如下:
CLObject events = clCreateUserEvent(g_pCLPlatform->clCtx, &status);
        // 第一种方式,CL_MEM_ALLOC_HOST_PTR, 并且使用Map方法初始化设备Buffer
        m_pCLSrc        = clCreateBuffer(g_pCLPlatform->clCtx, CL_MEM_READ_ONLY   | CL_MEM_ALLOC_HOST_PTR, m_pSrcWrapper->color_pitch * m_stuSrc.GetHeight(), NULL/*m_pSrcWrapper->color*/, &status);
        m_pTimeClock->Start();
        void        *pBuffer = clEnqueueMapBuffer(g_pCLPlatform->clCmdque, m_pCLSrc, CL_TRUE, CL_MAP_WRITE, 0, m_pSrcWrapper->color_pitch * m_stuSrc.GetHeight(), 0, NULL, &events, &status);
        m_pTimeClock->End();
        *m_pTimeClock - _T("OPENCL Map Device Mem Object Cost GPU Time:") - NXGamutConverterCL::getRunTime(events) - _T("\n");
        *m_pTimeClock << _T("OPENCL Map Device Mem Object Cost All Time:");
        m_pTimeClock->Start();
        memcpy(pBuffer, m_pSrcWrapper->color, m_pSrcWrapper->color_pitch * m_stuSrc.GetHeight());
        m_pTimeClock->End();
        *m_pTimeClock << _T("OPENCL Init Device Mem Object With memcpy Cost All Time:");
        m_pTimeClock->Start();
        clEnqueueUnmapMemObject(g_pCLPlatform->clCmdque, m_pCLSrc, pBuffer, 0, NULL, &events);
        clWaitForEvents(1, &events);
        m_pTimeClock->End();
        *m_pTimeClock - _T("OPENCL UnMap Device Mem Object Cost GPU Time:") - NXGamutConverterCL::getRunTime(events) - _T("\n");
        *m_pTimeClock << _T("OPENCL UnMap Device Mem Object Cost All Time:");这段代买对应的输出如下图:

[img=110,0]http://bbs.gpuworld.cn/forum.php?mod=image&aid=1597&size=300x300&key=86f41fc608738cf7&nocache=yes&type=fixnone[/img]
2.第二种也是使用CL_MEM_ALLOC_HOST_PTR创建设备缓存对象,但是使用clEnqueueWriteBuffer初始化设备缓存对象。
代码如下:
        m_pTimeClock->Start();
        m_pCLSrc        = clCreateBuffer(g_pCLPlatform->clCtx, CL_MEM_READ_ONLY   | CL_MEM_ALLOC_HOST_PTR, m_pSrcWrapper->color_pitch * m_stuSrc.GetHeight(), NULL/*m_pSrcWrapper->color*/, &status);
        status                = clEnqueueWriteBuffer(g_pCLPlatform->clCmdque, m_pCLSrc, CL_TRUE, 0, m_pSrcWrapper->color_pitch * m_stuSrc.GetHeight(), m_pSrcWrapper->color, 0, NULL, &events);
         clWaitForEvents(1, &events);
         m_pTimeClock->End();
         *m_pTimeClock - _T("OPENCL Write Device Mem Object Cost GPU Time:") - NXGamutConverterCL::getRunTime(events) - _T("\n");
         *m_pTimeClock << _T("OPENCL Write Device Mem Object Cost All Time:");

这段代码对应的输出如下图:
[img=110,0]http://bbs.gpuworld.cn/forum.php?mod=image&aid=1598&size=300x300&key=22099f1abd8f90f0&nocache=yes&type=fixnone[/img]
两个运行结果可以看出来,使用clEnqueueWriteBuffer初始化设备缓存对象的效率比使用clEnqueueMapBuffer然后再解映射的效率高一些,这是不是不应该?从网上查到的资料说,不推荐使用clEnqueueWriteBuffer。
第二点让我困惑的是,内存Buffer上传至设备的效率。从GPU-Z的显卡属性截图可以看出,显卡系统总线PCIE的带宽是8GB/s, 上传一块大约32M的内存,理论数值应该是8毫秒左右,而实际上传时间是这个理论数值的2倍左右,造成这种误差的原因有哪些?