这种并行性可以在OpenCL中实现吗

这种并行性可以在OpenCL中实现吗,opencl,barrier,Opencl,Barrier,这是我的第一篇文章。我会尽量简短,因为我很珍惜你的时间。这个社区让我难以置信 我正在学习OpenCL,希望从下面的算法中提取一点并行性。我将只向您展示我正在处理的部分,我也尽可能地简化了它 1) 输入:两个长度为(n)的1D数组:A、B和n值。还包括值C[0],D[0] 2) 输出:两个长度为(n)的1D阵列:C、D 因此,这些都是递归定义,然而,对于给定的i值,C&D的计算可以并行进行(为了合理起见,它们显然更复杂)。天真的想法是为以下内核创建两个工作项: __kernel void test

这是我的第一篇文章。我会尽量简短,因为我很珍惜你的时间。这个社区让我难以置信

我正在学习OpenCL,希望从下面的算法中提取一点并行性。我将只向您展示我正在处理的部分,我也尽可能地简化了它

1) 输入:两个长度为(n)的1D数组:A、B和n值。还包括值C[0],D[0]

2) 输出:两个长度为(n)的1D阵列:C、D

因此,这些都是递归定义,然而,对于给定的i值,C&D的计算可以并行进行(为了合理起见,它们显然更复杂)。天真的想法是为以下内核创建两个工作项:

__kernel void test (__global float* A, __global float* B, __global float* C,
                    __global float* D, int n, float C0, float D0) {
    int i, j=get_global_id(0);

    if (j==0) {
       C[0] = C0;
       for (i=1;i<=n-1;i++) {
          C[i] = function1(C[i-1]);
          [WAIT FOR W.I. 1 TO FINISH CALCULATING D[i]];
       }
       return;
    }
    else {
       D[0] = D0;
       for (i=1;i<=n-1;i++) {
          D[i] = function2(C[i-1],D[i-1]);
          [WAIT FOR W.I. 0 TO FINISH CALCULATING C[i]];
       }
       return;
    }
}
\u内核无效测试(\u全局浮点*A、\u全局浮点*B、\u全局浮点*C、,
__全局浮点*D,整数n,浮点C0,浮点D0){
int i,j=获取全局id(0);
如果(j==0){
C[0]=C0;

对于(i=1;i在您的情况下,依赖关系是完全线性/递归的(我需要i-1)。甚至不像其他问题(减少、求和、排序等)那样是对数的。因此,这个问题不适合SIMD设备

您所能做的最好的事情就是在CPU中使用2个线程的方法。线程1将为线程2“生成”数据(C值)

非常幼稚的方法,例如:

Thread 1:
for(){
    ProcessC(i);
    atomic_inc(counter); //This function should unlock
}

Thread 2:
for(){
    atomic_dec(counter); //This function should lock
    ProcessD(i);
}

例如,
atomic_inc
atomic_dec
可以通过计数信号量来实现。

这可以在opencl中实现,但正如另一个答案所说,最多只能有两个线程

应该使用具有两个工作项的单个工作组来调用我的函数版本

__kernel void test (__global float* A, __global float* B, __global float* C, __global float* D, int n, float C0, float D0)
{
    int i;
    int gid = get_global_id(0);

    local float prevC;
    local float prevD;

    if (gid == 0) {
        C[0] = prevC = C0;
        D[0] = prevD = D0;
    }

    barrier(CLK_LOCAL_MEM_FENCE);

    for (i=1;i<=n-1;i++) {
        if(gid == 0){
            C[i] = function1(prevC);
        }else if (gid == 1){
            D[i] = function2(prevC, prevD);
        }

        barrier(CLK_LOCAL_MEM_FENCE);
        prevC = C[i];
        prevD = D[i];
    }
}
\uuuuu内核无效测试(\uuuu全局浮点*A、\uuu全局浮点*B、\uu全局浮点*C、\uuu全局浮点*D、整数n、浮点C0、浮点D0)
{
int i;
int gid=获取全局id(0);
本地浮动prevC;
局部浮动预防;
如果(gid==0){
C[0]=prevC=C0;
D[0]=prevD=D0;
}
屏障(CLK_本地_MEM_围栏);

对于(i=1;i也是如此,不是所有的全局工作项都一起执行(它们可能在块中完成,必须在下一组完成之前全部完成),所以等待不是一个选项。好吧,那么我的内核基本上会保持不变,除了你提到的那些原子函数?(不得不说,我仍在阅读有关openCL同步的文章,因此无法理解这些函数在atm上的作用)。如果在CPU上运行,代码会像预期的那样在if语句上分支?您是否要求保存C和D的所有值,还是只关心最终结果?能否定义
function1
function2
__kernel void test (__global float* A, __global float* B, __global float* C, __global float* D, int n, float C0, float D0)
{
    int i;
    int gid = get_global_id(0);

    local float prevC;
    local float prevD;

    if (gid == 0) {
        C[0] = prevC = C0;
        D[0] = prevD = D0;
    }

    barrier(CLK_LOCAL_MEM_FENCE);

    for (i=1;i<=n-1;i++) {
        if(gid == 0){
            C[i] = function1(prevC);
        }else if (gid == 1){
            D[i] = function2(prevC, prevD);
        }

        barrier(CLK_LOCAL_MEM_FENCE);
        prevC = C[i];
        prevD = D[i];
    }
}