Opencl 有没有一个好方法可以在飞行中选择正确的平台?

Opencl 有没有一个好方法可以在飞行中选择正确的平台?,opencl,Opencl,因为这是我正在使用的计算机,它有AMD、NVIDEA和Intel平台。我如何知道在用户计算机上使用哪个平台是正确的?我现在有一个循环,尝试为每个平台创建平台、设备、上下文和队列。如果在任何时候失败,它都会尝试下一个平台 readKernel(); numPlatforms = getNumPlatforms(); TEST platforms = getPlatforms(); TEST for(int i = 0; i < numPlatforms; i

因为这是我正在使用的计算机,它有AMD、NVIDEA和Intel平台。我如何知道在用户计算机上使用哪个平台是正确的?我现在有一个循环,尝试为每个平台创建平台、设备、上下文和队列。如果在任何时候失败,它都会尝试下一个平台

    readKernel();

    numPlatforms = getNumPlatforms(); TEST
    platforms = getPlatforms(); TEST
    for(int i = 0; i < numPlatforms; i++)
    {
        numDevices = getNumDevices(platforms[i]); TEST_AND_CONTINUE
        devices = getDevices(platforms[i], numDevices); TEST_AND_CONTINUE
        context = createContext(platforms[i], devices); TEST_AND_CONTINUE
        queue = getCommandQueue(context, devices[0]); TEST_AND_CONTINUE

        // all setup. can post info here ->  getDeviceInfo(devices[0]);
        break; 
    }
    program = createProgram(context, source); TEST
    buildProgram(program); TEST
    kernel = buildKernel(program, appName); TEST
readKernel();
numPlatforms=getNumPlatforms();试验
platforms=getPlatforms();试验
对于(int i=0;igetDeviceInfo(设备[0]);
打破
}
程序=创建程序(上下文、源);试验
构建程序(program);试验
kernel=buildKernel(程序,appName);试验

这是一个好办法还是有更好的办法?

像往常一样,对于这类问题,答案是:这取决于你的需要。或者换句话说,您需要定义什么是“正确的平台”

以下是我能想到的一些案例(我相信任何人都能找到其他案例):

  • 您使用特定于OCL版本的一些特性开发了内核。使用
    clGetPlatformInfo
    ,您可以查询当前的每个平台,以找到一个具有正确OCL版本的平台

  • 您针对特定类型的设备(CPU、GPU)优化了内核。您可以使用适当的标志(
    CL\u DEVICE\u TYPE\u TYPENAME
    )和
    clgetdeviceid
    )来筛选感兴趣的设备

  • 您希望尽可能多地并行计算,但必须将大量数据移动到设备。在这种情况下,您可能会发现在iGPU上运行内核可以提供最佳性能。借助功能
    clGetDeviceInfo
    和标志
    CL\u设备\u主机\u统一内存
    ,您可以确定是否有这样的设备可用

  • 使用
    clGetDeviceInfo
    功能,您还可以查询要使用的特定供应商扩展名(标记:
    CL\u设备扩展名
    )。请注意,
    clGetPlatformInfo
    还提供了平台支持的扩展列表

  •     readKernel();
    
        numPlatforms = getNumPlatforms(); TEST
        platforms = getPlatforms(); TEST
        for(int i = 0; i < numPlatforms; i++)
        {
            numDevices = getNumDevices(platforms[i]); TEST_AND_CONTINUE
            devices = getDevices(platforms[i], numDevices); TEST_AND_CONTINUE
            context = createContext(platforms[i], devices); TEST_AND_CONTINUE
            queue = getCommandQueue(context, devices[0]); TEST_AND_CONTINUE
    
            // all setup. can post info here ->  getDeviceInfo(devices[0]);
            break; 
        }
        program = createProgram(context, source); TEST
        buildProgram(program); TEST
        kernel = buildKernel(program, appName); TEST
    
  • 你有几个GPU可用,你想要一个“最佳性能”。仍然可以使用
    clGetDeviceInfo
    查询设备的某些规格。根据这些规格,您可以做出选择。例如,您可以确定设备是否有缓存(
    CL\u设备\u全局\u内存\u缓存类型
    ),如果是,则可以确定缓存大小(
    CL\u设备\u全局\u内存\u缓存线大小
    )。您还可以查询时钟频率(
    CL\u设备\最大时钟\频率
    )或设备上有多少计算单元可用(
    CL\u设备\最大计算\单元


通常一个好的通用用例是:

  • 获取所有平台
  • 获取每个平台的GPU和CPU/其他设备,将它们分成2个阵列
  • 是否有GPU设备可用?选择该平台和设备
  • 是否有CPU/其他设备可用?选择该平台和设备

  • 您可以使用
    clGetDeviceInfo()

    优化3点和4点,根据需要仅选择最佳GPU设备,添加在每个候选设备上运行一个短基准的代码,以便选择最适合手头问题的代码。也可以考虑并行使用所有合适的设备来加速在具有多个GPU的机器上执行。但是请注意,单CPU设备可以显示在多个平台下,即使只能使用它的一个平台实例。