opencl开始使用opencl


备注

本节概述了opencl是什么,以及开发人员可能想要使用它的原因。

它还应该提到opencl中的任何大型主题,并链接到相关主题。由于opencl的文档是新的,您可能需要创建这些相关主题的初始版本。


Opencl是一个api,可以将gpus,cpus和其他一些加速器(如pcie-fpga)充分利用类似C99的计算,但具有非常广泛的并发优势。一旦安装和基本实现完成,只有内核字符串(或其文件)中的简单更改会自动将算法应用于N个硬件线程。

开发人员可能希望使用它,因为优化内存空间或速度比在opengl或direct-x上执行相同操作要容易得多。它也是免版税的。设备内的并发是隐式的,因此不需要为每个设备进行显式多线程。但对于多设备配置,仍然需要cpu多线程。例如,当1000个线程作业发送到cpu时,线程同步由驱动程序处理。您只需告诉它工作组应该有多大(例如256个与虚拟本地内存​​连接)和同步点(仅在需要时)。

使用gpu进行通用操作几乎总是比cpu快。您可以更快地对事物进行排序,将矩阵乘以10倍的速度,并在“no”时间内连接内存中的sql表。任何200美元的桌面级gpu将在物理(有限元方法流体)工作负载上比任何200 $ cpu更快完成。 Opencl使其更容易和便携。当您使用C#完成工作时,您可以使用相同的内核和C ++项目(使用JNI和额外的C ++编译)轻松转移到java-opencl实现。

对于图形部分,您并不总是需要在cpu和gpu之间发送缓冲区。你可以在上下文创建部分使用“interop”选项纯粹在gpu上工作。使用interop,您可以在gpu的极限性能下准备几何。任何顶点数据都不需要pci-e。只发送一个“命令”,只在图形卡内部完成工作。这意味着没有数据的cpu开销。 Opencl准备几何数据,opengl渲染它。 CPU被释放。例如,如果cpu的单个线程可以在10000个周期内构建32x32的顶点球体,那么具有opencl的gpu可以在1000个周期内构建20个球体。


OpenCL 1.2的C#实现:64位窗口中AMD系统的平台数量

OpenCL是低级API,因此必须首先在“C空间”中实现。为此,需要从Khronos的网站下载头文件。我的硬件是AMD,能够支持1.2版,下载

opencl.h 
cl_platform.h 
cl.h 
cl_ext.h 
cl_egl.h 
cl_dx9_media_sharing.h 
cl_d3d10.h 
cl_d3d11.h 
cl_gl.h 
cl_gl_ext.h 
cl.hpp
 

这个页面

应该足够C ++绑定所以在将这些文件添加到项目并设置适当的二进制(和库)文件位置后(

用于64位amd库的$(AMDAPPSDKROOT)\ lib \ x86_64(首选amd app sdk的库)

用于64位opencl.dll的C:\ Windows \ SysWOW64(如果ICD是Linux系统,则为.so文件)

例如,但对于Intel-Nvidia不同,您可以在安装适当的驱动程序(例如amd的crimson)后开始查询平台列表(amd,intel,xilinx,nvidia)。驱动程序用于运行opencl应用程序(使用ICD),库和头文件用于简化开发。

要查询平台:

#define __CL_ENABLE_EXCEPTIONS
#include "stdafx.h"
#include <vector>
#include <CL/cl.hpp>

extern "C"
    {
       // when this class is created, it contains a list of platforms in "platforms" field.
       class OpenClPlatformList
       {
           public:
               std::vector<cl::Platform> platforms;
               int platformNum;
               OpenClPlatformList()
               {
                   platforms= std::vector< cl::Platform>();
                   cl::Platform::get(&platforms);
                   platformNum= platforms.size();
               }
        };


        // this is seen from C# when imported. Creates an object in memory.
        __declspec(dllexport)
            OpenClPlatformList * createPlatformList()
        {
            return new OpenClPlatformList();
        }

        __declspec(dllexport)
            int platformNumber(OpenClPlatformList * hList)
        {
            return hList->platformNum;
        }


        __declspec(dllexport)
            void deletePlatformList(OpenClPlatformList * p)
        {
            if (p != NULL)
                delete p;
            p = NULL;
        }


    }
 

可以内置到一个DLL(如OCLImplementation.dll)

并从C#侧使用它,

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;


namespace WrapperCSharp
{
    public class WrapperCSharp
    {
        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern IntPtr createPlatformList();

        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern int platformNumber(IntPtr hList);

        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern void deletePlatformList(IntPtr hList);
    }
}
 

当然,必须通过C#项目看到dll,只需将它放在项目的可执行文件附近即可。

现在,如果示例计算机至少有一个支持opencl的平台,

IntPtr platformList = createPlatformList(); // just an address in C-space
int totalPlatforms = platformNumber(platformList); // AMD+NVIDIA systems should have "2"
deletePlatformList(platformList); //
 

totalPlatforms变量必须至少具有“1”值。然后,您可以使用C空间中的平台变量,使用其他函数迭代所有平台,以查询所有设备,如CPU,GPU和特殊用途加速器,如phi或某些fpga。

人们不会简单地将所有这些C ++写入C#包装器以用于时间关键型项目。有许多为C#,Java和其他语言编写的包装器。对于java,有一个“Aparapi”是“java字节码到opencl-c”转换器api,它将您在java中纯粹编写的内容转换为动态的gpu-parallel版本,因此它具有一定的可移植性。

OpenCL和C#

对于C#,存在许多包装器,它们提供与OpenCL通信的接口。

  • OpenCL.NET:这是最低级别的包装器之一。它为C#提供了OpenCL API的完整实现,而根本不添加任何抽象。因此,C / C ++示例可以轻松移植到此库中。目前唯一的项目页面是在codeplex上,它于15.12.2017关闭,但该程序包在NuGet上可用

https://openclnet.codeplex.com/

  • NOpenCL:这个库提供了C#和OpenCL之间的抽象接口。

短期目标是提供易于使用的抽象层,可以在不牺牲性能的情况下访问OpenCL的全部功能。

https://github.com/tunnelvisionlabs/NOpenCL

  • Cloo:

Cloo是一个开源,易于使用的托管库,它使.NET / Mono应用程序能够充分利用OpenCL框架。

https://sourceforge.net/projects/cloo/

先决条件

如果您的计算机内部有现代CPU或图形卡(GPU),那么您可能已经为OpenCL中的第一步做好了准备。找出你的处理器是否支持OpenCL通常可以通过制造商的主页完成,一个良好的第一个开始是官方文档在

https://www.khronos.org/conformance/adopters/conformant-products#opencl

什么是OpenCL?

开放计算语言(OpenCL)是一个用于编写在CPU,GPU和其他并行处理器和加速器上执行的程序的框架。

OpenCL指定了一种编程语言(基于C),它提供对命名的片上内存的访问,并行执行任务的模型,以及同步这些任务的能力。

什么是OpenCL?

OpenCL是Open C omputing L anguage的缩写。 OpenCL是跨异构平台的并行编程框架,称为计算设备 ,范围从CPU到GPU,再到更特殊的平台,如FPGA。 OpenCL为这些计算设备上的并行计算提供了标准接口,但也提供了设备间并行性。它指定了一种基于C99的编程语言,以及在支持OpenCL的设备上实现的基本功能的最低要求。 OpenCL还描述了一种抽象的计算和内存模型,尽可能通用,以便在不同平台之间直接重用代码。