蚊章汇 - Tartan Llama
type: channel
link: https://linuxcn.bwsl.wang/author/612/
description: Tartan Llama
items: 机器学习的新捷径：通过 SYCL 在 GPU 上加速 C++

机器学习的新捷径：通过 SYCL 在 GPU 上加速 C++
type: item
date: 2017-06-14T01:47:00+08:00
description: 在机器学习、计算机视觉以及高性能计算领域，充分利用显卡计算应用程序的能力已成为当前的热门。类似 OpenCL 的技术通过硬件无关的编程模型展现了这种能力，使得你可以编写抽象于不同体系架构的代码。它的目标是“一次编写，到处运行”，不管它是 Intel CPU、AMD 独立显卡还是 DSP 等等。不幸的是，对于日常程序员，OpenCL 的学习曲线陡峭；一个简单的 Hello World 程序可能就需要上百行晦涩难懂的代码。因此，为了减轻这种痛苦，Khronos 组织已经开发了一个称为 SYCL 的新标准，这是一个在 OpenCL 之上的 C++ 抽象层。通过 SYCL，你可以使用干净、现代的 C++ 开发出这些通用 GPU（GPGPU）应用程序，而无需拘泥于 OpenCL。下面是一个使用 SYCL 开发，通过并行 STL 实现的向量乘法事例：#include <vector> #include <iostream> #include <sycl/execution_policy> #include <experimental/algorithm> #include <sycl/helpers/sycl_buffers.hpp> using namespace std::experimental::parallel; using namespace sycl::helpers; int main() { constexpr size_t array_size = 1024*512; std::array<cl::sycl::cl_int, array_size> a; std::iota(begin(a),end(a),0); { cl::sycl::buffer<int> b(a.data(), cl::sycl::range<1>(a.size())); cl::sycl::queue q; sycl::sycl_execution_policy<class Mul> sycl_policy(q); transform(sycl_policy, begin(b), end(b), begin(b), [](int x) { return x*2; }); } } 为了作为对比，下面是一个通过 C++ API 使用 OpenCL 编写的大概对应版本（无需花过多时间阅读，只需注意到它看起来难看而且冗长）。#include <iostream> #include <array> #include <numeric> #include <CL/cl.hpp> int main(){ std::vector<cl::Platform> all_platforms; cl::Platform::get(&all_platforms); if(all_platforms.size()==0){ std::cout<<" No platforms found. Check OpenCL installation!\n"; exit(1); } cl::Platform default_platform=all_platforms[0]; std::vector<cl::Device> all_devices; default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices); if(all_devices.size()==0){ std::cout<<" No devices found. Check OpenCL installation!\n"; exit(1); } cl::Device default_device=all_devices[0]; cl::Context context({default_device}); cl::Program::Sources sources; std::string kernel_code= " void kernel mul2(global int* A){" " A[get_global_id(0)]=A[get_global_id(0)]*2;" " }"; sources.push_back({kernel_code.c_str(),kernel_code.length()}); cl::Program program(context,sources); if(program.build({default_device})!=CL_SUCCESS){ std::cout<<" Error building: "<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device)<<…