转自:https://www.cnblogs.com/willhua/tag/OpenCL/
有两种方式实现从主机到CL设备的数据传递,
第一种:
1 cl_mem input = clCreateBuffer(context,CL_MEM_READ_ONLY,sizeof(float) * DATA_SIZE, NULL, NULL); 2 clEnqueueWriteBuffer(command_queue, input, CL_TRUE, 0, sizeof(float) * DATA_SIZE, inputdata, 0, NULL, NULL);
第二种:
1 cl_mem input = clCreateBuffer(context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float) * DATA_SIZE, inputdata, NULL);
- 这两种写法可以说是没啥区别,但是如过第二中写法中CL_MEM_COPY_HOST_PTR换成CL_MEM_USE_HOST_PTR,那么根据文档的说法,第二种并不会把主机的inputdata复制到设备,而仅仅是cache
- 如果inputdata仅仅会初始化一次,那么使用第二种方法看起来更加便捷;但是如果对inputdata要进行多次更新,那么使用第一种的方式更好,可以调用clEnqueueWriteBuffer进行更新
- 使用第一种可以在clEnqueueWriteBuffer中使用event来测量耗时
- 第一种写法会先在主机创建一个second temporary buffer on the host,然后等到设置这个buffer到kernel的时候再把数据拷贝到设备上。这样,就可能会在一个短暂的时候,主机上有两份内存。如果buffer比较大,就会引发问题。而第二种方法则是立即把数据复制的设备,没有额外的临时内存分配。参考
- 如果clcontext上绑定了多个device,那么使用第二种方法则会在每个device上都分配该buffer。如果只想对某个设备分配该buffer,那么就应该使用与device绑定了的clEnqueueWriteBuffer。参考
- 然而,在高通的优化指南中,这两种做法都不推荐。推荐使用Zero Copy的写法,其关键在于CL_MEM_ALLOC_HOST_PTR的应用
1 // First set cl_mem_flags input in clCreateBuffer: 2 cl_mem Buffer = clCreateBuffer(context, 3 CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, 4 sizeof(cl_ushort) * size, 5 NULL, 6 &status); 7 //Then use the map function to return a pointer to the host: 8 cl_uchar *hostPtr = (cl_uchar *)clEnqueueMapBuffer( 9 commandQueue, 10 Buffer, 11 CL_TRUE, 12 CL_MAP_WRITE, 13 0, 14 sizeof(cl_uchar) * size, 15 0, NULL, NULL, &status); 16 17 //Host updates the buffer using the pointer hostPtr 18 memcpy(hostPtr, sizeof(cl_uchar) * size, datafromhost); 19 20 //Unmapped the object 21 status = clEnqueueUnmapMemObject( 22 commandQueue, 23 Buffer, 24 (void *) hostPtr, 25 0, NULL, NULL); 26 27 //The object can be used by OpenCL kernels
标签:CL,Copy,cl,MEM,opencl,buffer,Zero,sizeof,NULL From: https://www.cnblogs.com/peifx/p/16987327.html