在一些有多个显卡,比如一个核芯显卡和一个独立显卡的系统中使用显卡加速,OpenCL默认的设备可能不是性能更好的独立显卡。这时候可以用下述方法更换显卡,代码如下。本例在VS2015和OpenCL3.0下测试通过:
const string kernel = u8R"( kernel void reduceSum(global int* num, global int* result) { unsigned int id = get_global_id(0); result[id] = 2 * num[id]; })"; void main() { cl::Platform device = cl::Platform::getDefault(); const int which = 0; /* 指定显卡索引 */ cl::vector<cl::Device> devs; device.getDevices(CL_DEVICE_TYPE_ALL, &devs); string name; devs[which].getInfo(CL_DEVICE_NAME, &name); /* 设备名称 */ cl::Context context(devs[which]); cl::CommandQueue queue(context); cl::Program program(context, kernel); try { program.build("-cl-std=CL2.0"); } catch (...) { cl_int buildErr = CL_SUCCESS; auto buildInfo = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(&buildErr); for (auto &pair : buildInfo) { std::cerr << pair.second << std::endl << std::endl; } } auto kernelFunc = cl::KernelFunctor<cl::Buffer, cl::Buffer>(program, "reduceSum"); vector<int> array1(100000, 1); vector<int> result1(100000, 0); int64 t1, t2; t1 = getTickCount(); cl::Buffer inputBuffer(queue, array1.begin(), array1.end(), true); cl::Buffer outputBuffer(queue, result1.begin(), result1.end(), false); kernelFunc(cl::EnqueueArgs(queue, cl::NDRange(100000)), inputBuffer, outputBuffer); cl::copy(queue, outputBuffer, result1.begin(), result1.end()); t2 = getTickCount(); qDebug() << (t2 - t1) / getTickFrequency() * 1000 << "ms" << endl; }
本人是自学OpenCL的,一开始由于不知道cl::Buffer的构造函数和cl::copy(...)函数有多个重载可以指定Context或CommandQueue参数导致调了几天都没有测试成功。表现就是编译正确但是运行的时候核函数输出不对。这里需要注意下,OpenCL的传输数据和输入核函数的操作基本上都是基于CommandQueue的,需要指定一个命令队列。如果不指定则函数内部会取默认命令队列操作。
上述代码中的getTickCount()是OpenCV中的函数,qDebug()是Qt的输出文本的函数,如不需要可以删掉。它们不影响OpenCL的运行。
标签:cl,int,OpenCL,result1,queue,切换,显卡 From: https://www.cnblogs.com/mengxiangdu/p/18022326