码迷,mamicode.com
首页 > 其他好文 > 详细

OpenCL2.0特性之SVM

时间:2015-06-04 17:12:15      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:opencl   svm   

      在OpenCL2.0中,增加了SVM(shared virtual memory)的特性。在开始讲解SVM之前,我们先用图片来看下OpenCL1.2中主机与设备端的地址空间:

技术分享

                                                 图1 OpenCL1.2中主机与设备端地址空间

        从图1可以看到,主机与设备具有不同的地址空间,各自需要对各自的内存进行管理。彼此之间不能直接访问对方的地址空间。所以,两者之间数据需要通信的话,只能把数据在主机与设备间来回拷贝,或者把设备端地址空间map /unmap到主机端。对于这样一种模式下,如果我们要想在设备端处理主机端的链表、树之类的数据。我们只能鞭长莫及!对于异构平台,我们就真的没办法愉快地处理链表之类的数据么?技术是发展的,有需求就必有技术来解决!

     从CUDA6以后,GPU与CPU之间支持统一寻址(Unified Memory)  ,GPU与CPU间可以直接访问彼此的地址空间,不需要我们人为的数据拷贝。这给异构计算又带入了一个新的高度,我们可以处理链表数据啦!既然CUDA都开始支持了,OpenCL也不能落后呀。在OpenCL2.0中,增加了共享虚拟内存(shared virtual memory),我们还是以一张图片来形象的描述:

技术分享

                                              图2 OpenCL2.0中主机与设备端地址空间

      从图2可以看到,图1中原来两个彼此不相交的地址空间现在有个公共交集,这个公共交集就是SVM.。对于SVM的地址空间,主机和设备都可以直接访问,妈妈再也不用担心异构平台的数据访问方式了!

说完了SVM的意义,我们来聊聊SVM的具体细节。

        对于SVM的创建,OpenCL2.0中有两种方式,一种缓冲分配(buffer allocation),另一种是系统分配(System allocation):

        1、所谓缓冲分配,就是我们使用OpenCL API函数clSVMAlloc来分配,然后使用clSetKernelArgSVMPointer把分配的SVM作为内核参数传入

         2、所谓系统分配,就是在主机端,我们可以使用malloc,new之类的系统分配内存函数来分配空间,然后使用clSetKernelArgSVMPointer把分配的SVM作为内核参数传入。

        对于SVM的类型,OpenCL2.0也是有两种类型:一种是粗粒度;另一种是细粒度:

        1、粗粒度SVM:共享发生在OpenCL缓冲内存对象区域粒度。在同步点强制内存一致性,使用map/unmap命令来更新主机与设备间的数据。粗粒度的SVM与OpenCL1.2中使用缓冲对象类似,不过唯一不同的是:我们不需要来回拷贝数据,设备与主机可以直接访问对方的数据,这才是重点!

       2、所谓细粒度SVM:共享发生在OpenCL缓冲对象单个的加载/存储粒度。内存一致性在同步点得到保证。

        好,结合SVM分配方式和SVM类型,可以把OpenCL2.0中的SVM分为:粗粒度缓冲SVM,细粒度缓冲SVM,细粒度系统SVM。(木有粗粒度系统SVM)。对于你的OpenCL设备(请确保你的设备支持OpenCL2.0),到底支持上述三种的哪三种呢?我们可以通过如下代码查询:

         

         cl_device_svm_capabilities svm;
	clGetDeviceInfo(*device,CL_DEVICE_SVM_CAPABILITIES,sizeof(svm),&svm,NULL);
	if(svm&CL_DEVICE_SVM_FINE_GRAIN_SYSTEM)
		printf("CL_DEVICE_SVM_FINE_GRAIN_SYSTEM\n");
	if(svm&CL_DEVICE_SVM_FINE_GRAIN_BUFFER)
		printf("CL_DEVICE_SVM_FINE_GRAIN_BUFFER\n");
	if(svm&CL_DEVICE_SVM_COARSE_GRAIN_BUFFER)
		printf("CL_DEVICE_SVM_COARSE_GRAIN_BUFFER\n");
       在我的AMD A10-7400 Radeon R6平台上,当设备为CL_DEVICE_TYPE_GPU时,输出为:

CL_DEVICE_SVM_FINE_GRAIN_BUFFER
CL_DEVICE_SVM_COARSE_GRAIN_BUFFER
      对于细粒度系统SVM,AMD当前是不支持的。

      粗粒度缓冲SVM和细粒度缓冲SVM大致用法,如下表格所示

Coarse-grained SVM
(Map/Unmap is requred)
fine-grained SVM buffer
float* p = (float*)clSVMAlloc(…);

clEnqueueSVMMap(…,
    CL_TRUE,  // block until map is done
    p, …);


// Initialize SVM buffer
p[i] = …;

clEnqueueSVMUnmap(…, p, …);

clEnqueueNDRange(…);

clEnqueueSVMMap(…,
    CL_TRUE,  // block until map is done
    p, …);

// Read the data produced by the kernel
… = p[i];

clEnqueueSVMUnmap(…, p, …);
float* p = (float*)clSVMAlloc(…);







// Initialize SVM buffer
p[i] = …;



clEnqueueNDRange(…);

clFinish(…);




// Read the data produced by the kernel
… = p[i]; 

具体的SVM例子,请移步这里

OpenCL2.0 SVM的讲解,就到这吧!

 ps:最后唠叨一句:对于SVM,方便了我们码农编程,从硬件上来说,OpenCL设备与主机不一定是共享物理内存的。

     

     

OpenCL2.0特性之SVM

标签:opencl   svm   

原文地址:http://blog.csdn.net/wcj0626/article/details/46360605

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!