我们可以查看当前设备中,有哪些厂商提供了 OpenCL 的支持,以及运算平台是啥。例如,在 Surface Book (with Nvidia GPU) 上,我们调用以下代码看看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//获取所有平台 var platforms = ComputePlatform.Platforms;
foreach(var platform in platforms) { Console.WriteLine($"{platform.Name},{platform.Version}");
//获取该平台下的计算设备 var devices = platform.QueryDevices(); foreach(var device in devices) { Console.WriteLine($" Device:{device.Name}"); } }
输出:
1 2 3 4 5 6
Intel(R) OpenCL, OpenCL 2.0 Device:Intel(R) HD Graphics 520 Device:Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz
NVIDIA CUDA, OpenCL 1.2 CUDA 8.0.0 Device:GeForce GPU
可以看出这台机器上有两个支持 OpenCL 的平台,英特尔的CPU和英伟达的GPU,其中,INTEL CPU 里又有两个计算设备 CPU 和集成的核显 HD520。 毫无疑问,在 OpenCL 上,英伟达的GPU可以提供比 Intel CPU 高得多的性能,毕竟,GPU的流处理器数量要比CPU上那可怜的核显上的要多得多。
staticvoid Matrix_mul_opencl(int r) { //选取设备 var platform = ComputePlatform.Platforms.FirstOrDefault(); var device = platform.Devices.FirstOrDefault();
//设置相关上下文 var properties = new ComputeContextPropertyList(platform); var context = new ComputeContext(new[] { device }, properties, null, IntPtr.Zero);
//命令队列,用于控制执行的代码 ComputeCommandQueue commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);
//读取opencl代码 var code = File.ReadAllText("matrix.cl");
//编译 var program = new ComputeProgram(context, code); try { program.Build(null, null, null, IntPtr.Zero); } catch (Exception ex) { throw; }
//创建核心代码,就是cl代码中以kernel标识,函数签名为MatrixMul的函数 var kernel = program.CreateKernel("MatrixMul");
//矩阵规模 int rank = r; //储存计算结果的数组 var result = new ComputeBuffer<int>(context, ComputeMemoryFlags.WriteOnly, rank * rank); var matrix = CreateMatrix(context, rank);