如何优化我的OpenCl内核

Vis*_*ngh 1 opencl

我已经分离出一些彼此不同的函数,但需要在不同的工作项中并行运行.因此,当调用内核时,需要决定必须执行哪个函数.

void call_calc0() {
    // code
}

void call_calc1() {
    // code
}

void call_calc2() {
    // code
}

void call_calc3() {
    // code 
}

__kernel void perform (__global double* A, __global double* B) {
    int idx = get_global_id(0);
    if (idx == 0) {
        call_calc0();
    } else if (idx == 1) {
        call_calc1();
    } else if (idx == 2) {
        call_calc2();
    } else if (idx == 3) {
        call_calc3();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果有256/512个工作项,则此代码示例将不是正确的方法.我该如何优化呢?

mfa*_*mfa 6

如果可能,您最好的优化是使用四个不同的内核.您正在调用具有多个组大小的此内核,并行执行时会出现问题.

如果可能的话,尝试分离全局内存或以非常小心,非碰撞的方式使用它.这应该允许您创建四个单独的内核,并摆脱条件代码执行.

遇到第一个if/case时,该组的某些工作项将运行代码,但其他75%的工作项将等待.大多数opencl设备,尤其是GPU,都以这种方式运行.当前25%的工作项完成时,它们将等待下一个if/case代码执行.

这适用于opencl中的所有分支,例如if/else,switch,for和while/do.每当组中的某些工作项不满足条件时,它们会等待满足条件的其他工作项.然后在'if'组等待时执行'else'工作项组.

另一种看待它的方法是比较CPU和GPU硬件.CPU有很多专用于分支预测和高速缓冲存储器的晶体管.GPU本质上更具矢量基础,并且最近才开始支持CPU的一些更先进的流控制功能.