OpenCL2.0特性之SVM

2023-11-19

      在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设备与主机不一定是共享物理内存的。

     

     

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCL2.0特性之SVM 的相关文章

  • 数组大小和复制性能

    我确信这个问题之前已经得到了回答 但我找不到一个好的解释 我正在编写一个图形程序 其中管道的一部分将体素数据复制到 OpenCL 页面锁定 固定 内存 我发现这个复制过程是一个瓶颈 并对一个简单的性能进行了一些测量std copy 数据是浮
  • Python OpenCV SVM 实现

    因此 我有一个包含样本图像的矩阵 全部转换为向量 该矩阵通过 PCA LDA 运行 还有一个向量表示每个图像所属的类 现在我想使用 OpenCV SVM 类来训练我的 SVM 我使用的是 Python OpenCV 2 3 1 但我在定义参
  • 并行化 std::nth_element 和 std::partition

    我正在移植使用的 C 代码std nth element and std partition到 OpenCL nth element http www cplusplus com reference algorithm nth elemen
  • OpenCL:头文件的附加目录

    OpenCL 规范中写道5 6 3 构建选项 5 6 3 1 预处理器选项 I dir Add the directory dir to the list of directories to be searched for header f
  • OpenCL 产生错误的计算

    我一直尝试使用openCL做一些计算 但结果不正确 我输入了三个 float3 如下所示 300000 0 0 300000 300000 0 300000 300000 300000 进入这个内核 kernel void gravitat
  • 为什么 AMD GCN 使用非零 NULL?

    这次提交 https reviews llvm org rL289252 says In amdgcn https en wikipedia org wiki Graphics Core Next目标 全局 常量和通用地址空间中的空指针取值
  • 有多少线程(或工作项)可以同时运行?

    我是 GPGPU 编程新手 正在研究 OpenCL 的 NVIDIA 实现 我的问题是如何计算 GPU 设备的限制 线程数 据我了解 有许多工作组 相当于 CUDA 中的块 其中包含许多工作项 cuda 线程 如何获取我的卡上存在的工作组数
  • GPGPU:普通 PC 陷入困境的后果

    我在一本书中读到 在波前或扭曲中 所有线程共享一个公共程序计数器 那么它的后果是什么呢 为什么这很重要 NVIDIA GPU 一次执行 32 个线程 扭曲 AMD GPU 一次执行 64 个线程 波前 控制逻辑 读取和数据路径的共享减少了面
  • PyOpenCL 矩阵乘法

    我有使用 pyopenCL 进行矩阵乘法的代码 我的问题是某些矩阵的结果是错误的 我不明白为什么 经过一番研究后 我认为它与类似的全球规模有关 但我不明白如何设置该值 例如 使用 numpy dtype float32 的矩阵 矩阵1 0
  • 有适用于 mac os X 10.8 的 opencl 分析器吗?

    我试图找到 OpenCL 内核中的瓶颈 是否可以在 mac os X 上分析 OpenCL 程序 我发现 gDebuggerhttp www gremedy com http www gremedy com 但需要 10 5 或 10 6
  • 如何使用带有面部特征的 openCV 训练支持向量机(svm)分类器?

    我想使用svm分类器进行面部表情检测 我知道 opencv 有一个 svm api 但我不知道训练分类器的输入应该是什么 到目前为止我读了很多论文 他们都说在面部特征检测之后训练分类器 到目前为止我所做的 人脸检测 每帧计算16个面部点 下
  • OpenCL:为什么指向指针的指针不能作为参数传递给内核函数?

    你好 我只是想澄清一下为什么我们不能将 2D 数组指针作为参数传递给内核 为什么不允许 如果我使用它作为参数会发生什么 在内部 因为我知道代码会给出一些错误 请只做那些需要的 因为在 OpenCL 1 x 中设备有一个独立的地址空间 在设备
  • OpenCL 在调用 clGetPlatformIDs 时崩溃

    我是 OpenCL 新手 在配备 Intel R HD Graphics 4000 运行 Windows 7 的 Core i5 计算机上工作 我安装了支持 OpenCL 的最新 Intel 驱动程序 GpuCapsViewer 确认我有
  • 插入符 rfe + sum 与 ROC 中的特征选择

    我一直在尝试使用插入符包应用递归功能选择 我需要的是 ref 使用 AUC 作为性能衡量标准 经过一个月的谷歌搜索后 我无法让该过程正常运行 这是我使用过的代码 library caret library doMC registerDoMC
  • 如何加载之前存储的svm分类器?

    我正在 Visual Studio 中使用 openCV SVM OpenCV 2 4 4 0 我训练它 mySVM train trainingDataMat labelsMat Mat Mat params 已保存 mySVM save
  • 在 OpenCL 内核中使用 _ 常量限定符

    我在使用时遇到问题 持续的我的 OpenCL 内核中的限定符 我的平台是雪豹 我尝试在 GPU 上初始化 CL 只读内存对象 将常量数组从主机复制到其中 然后我设置内核参数就像 global内存参数 但这不起作用 但我没有看到任何错误或警告
  • 使用 OpenCL 支持构建 OpenCV

    在 CMake 中 我使用 OpenCL Enable ON 构建了 OpenCV 它自动检测到OPENCL INCLUDE DIR路径但是OPENCL LIBRARY即使单击配置后也是空的 为了OPENCL LIBRARY我也没有看到浏览
  • 在 Mac OS X 10.7.4 上使用 OpenCL 禁用 Nvidia 看门狗

    我有一个 OpenCL 程序 对于小问题运行良好 但是当运行较大的问题超过 Nvidia 硬件上运行内核的 8 10 秒时间限制时 虽然我没有将显示器连接到我正在计算的 GPU Nvidia GTX580 上 但一旦内核运行大约 8 10
  • 在内核 OpenCL 中实现 FIFO 的最佳方法

    目标 在 OpenCL 中实现下图所示 OpenCl 内核所需的主要内容是将系数数组和临时数组相乘 然后最后将所有这些值累加为 1 这可能是最耗时的操作 并行性在这里非常有帮助 我正在为内核使用一个辅助函数来执行乘法和加法 我希望这个函数也
  • 使用 libsvm 交叉验证后重新训练

    我知道交叉验证用于选择好的参数 找到它们后 我需要在不使用 v 选项的情况下重新训练整个数据 但我面临的问题是 在使用 v 选项训练后 我得到了交叉验证精度 例如 85 没有模型 我看不到 C 和 gamma 的值 在这种情况下我该如何重新

随机推荐