OpenCL是一个并行计算库。在Visual Studio中的配置类似于OpenCV,只需要把开发包下载下来,里面有include、lib、bin文件夹,在项目设置里添加上就行了。一般Windows系统自己带的就有OpenCL.dll,在Windows/System32/文件夹里。不同于英伟达的CUDA编程自己搞了个编译器集成到Visual Studio中。OpenCL不需要编译器,它是将GPU核函数源代码作为字符串传给SDK即时解释执行的。
- 官网(官网博客里有OpenCL SDK的介绍):OpenCL Overview - The Khronos Group Inc
- OpenCL SDK的GitHub链接:GitHub - KhronosGroup/OpenCL-SDK: OpenCL SDK,这个开源仓库说明是需要下载下来自己用CMake编译,有时间的可以自己倒腾,反正我没编译成功,Visual Studio报错说缺少文件。不过这个网页里有编译好的SDK可以点击右侧Releases栏链接查看下载。
- 编译好的OpenCL SDK链接:Releases · KhronosGroup/OpenCL-SDK (github.com)
- 入门教程:OpenCL 在Windows上搭建开发环境|极客笔记 (deepinout.com)
下面将给出一个例子,需要读者熟悉C++11以上标准。该例子里核函数运算量比较大,因为测试发现过于简单的运算CPU更快。此例子在Release版下GPU运算速度略高于CPU。测试环境是VS2017、OpenCL306,CPU型号是Intel Core i5-7400,核芯显卡。当然在OpenCL SDK里的opencl.hpp头文件里也有一个官方例子说明了使用显卡加速的流程。
const int numElements = 1000000; int main() { std::string kernel{ R"CLC( kernel void vectorOpr(global const float *input, global float *output) { int i = get_global_id(0); for (int j = 0; j < 10; j++) { if (input[i] < 50) { output[i] += 0; } else if (input[i] > 100) { output[i] += 1; } else { output[i] += sin(input[i] - 50) / cos(input[i] - 50); } } } )CLC" }; cl::Program anyProgram(kernel); try { anyProgram.build("-cl-std=CL2.0"); } catch (...) { cl_int buildErr = CL_SUCCESS; auto buildInfo = anyProgram.getBuildInfo<CL_PROGRAM_BUILD_LOG>(&buildErr); for (auto &pair : buildInfo) { std::cerr << pair.second << std::endl << std::endl; } return 1; } std::mt19937 mt; cl::coarse_svm_vector<float> input(numElements, 75); cl::vector<float> output(numElements, 1); for (auto& item : input) { item = mt() % 200; } cl::Buffer buff(output.begin(), output.end(), false); auto anyKernel = cl::KernelFunctor<float*, cl::Buffer&>(anyProgram, "vectorOpr"); std::chrono::system_clock::time_point t1, t2; t1 = std::chrono::system_clock::now(); anyKernel(cl::EnqueueArgs(cl::NDRange(numElements), cl::NDRange(1)), input.data(), buff); copy(buff, output.begin(), output.end()); t2 = std::chrono::system_clock::now(); std::cout << "显卡(ms):" << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << std::endl; cl::vector<float> A(numElements, 75); cl::vector<float> C(numElements, 1); for (auto& item : A) { item = mt() % 200; } t1 = std::chrono::system_clock::now(); for (int i = 0; i < numElements; i++) { for (int j = 0; j < 10; j++) { if (A[i] < 50) { C[i] += 0; } else if (A[i] > 100) { C[i] += 1; } else { C[i] += sin(A[i] - 50) / cos(A[i] - 50); } } } t2 = std::chrono::system_clock::now(); std::cout << "CPU(ms):" << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << std::endl; return 0; }
标签:std,入门,cl,例程,OpenCL,input,output,SDK From: https://www.cnblogs.com/mengxiangdu/p/17384014.html