OpenCL代码的优化?

OpenCL代码的优化?,opencl,Opencl,我在OpenCL中有一个代码,它以从给定点递减4的步骤添加数组元素 这是代码-rp是源数组,out是输出数组): 生成的rp[i]保存在代码中的temp中,最后保存在out[gid]中 所以,要添加这个序列,需要循环,而且需要很多时间。。。 如果有某种方法,可以缓存前面的总和,或者完全删除循环,那就太好了 如何改进此代码以消除循环?首先,我建议您消除可能的uchar溢出: __kernel void subFilter( __global unsigned char *rp,

我在OpenCL中有一个代码,它以从给定点递减4的步骤添加数组元素

这是代码-
rp
是源数组,
out
是输出数组):

生成的
rp[i]
保存在代码中的temp中,最后保存在
out[gid]

所以,要添加这个序列,需要循环,而且需要很多时间。。。 如果有某种方法,可以缓存前面的总和,或者完全删除循环,那就太好了


如何改进此代码以消除循环?

首先,我建议您消除可能的uchar溢出:

__kernel void subFilter(
    __global unsigned char  *rp,
    __global unsigned char  *out,
    int                     istop,
    int                     bpp)
{
    int gid = get_global_id(0), i = gid;
    unsigned char temp = 0;

    if(gid>=bpp){
        i=gid;

        while(i>=0)
        {
            if(temp > 255 - rp[i])
            {
                temp -= 255 - rp[i];
            }
            else
            {
                temp += rp[i];
            }

            i -= bpp;
        }

        //masked
        out[gid]=(temp & 0xff);  
    }
    else if(gid<bpp){
        out[gid]=rp[gid];
    }
}
\u内核无效子筛选器(
__全局无符号字符*rp,
__全局无符号字符*out,
int istop,
int(bpp)
{
int gid=get_global_id(0),i=gid;
无符号字符温度=0;
如果(gid>=bpp){
i=gid;
而(i>=0)
{
如果(温度>255-rp[i])
{
温度-=255-rp[i];
}
其他的
{
温度+=rp[i];
}
i-=bpp;
}
//蒙面
输出[gid]=(温度和0xff);
}

else if(gid消除循环中的条件代码可能会提高性能:

__kernel void subFilter(__global unsigned char* rp,__global unsigned char *out,int istop,int bpp)
{
    int gid = get_global_id(0);//add the offset by bpp to access the next gid
    int i;
    unsigned char temp=0;

    out[gid]=rp[gid];
    if(gid>=bpp){
        i=gid;
        while(i>=0)
        {
            temp+=rp[i];
            i-=bpp;
        }
        out[gid]=(temp & 0xff);  //masked
    }
}

除了格式设置之外,内核中还有一些语法错误。请发布代码的工作版本。如果代码在外部编辑器中缩进正确,您可以将其复制粘贴到问题中,全部选中,然后执行
ctrl-k
(或单击“代码示例”按钮)。这应该保留缩进。这是实际工作的内核..在问题中更新了
i
初始化在哪里?抱歉,删除注释时,该注释也被删除了,我现在已经更正了。我对您的措辞做了一些更改,请随意撤销或进一步修改。整数升级的C语言规则nts“可能的uchar溢出”在原始代码中。我的意思是变量将在uchar值范围内&不会进行更大类型的转换。我的算法尝试解码PNG图像,这部分实现子过滤器。这只是将当前像素与前一个像素相加。bpp定义每个像素和每个组件使用的字节(R,G,B)被添加到相应的部分。在顺序代码中,这些值在当前位置被添加和更新,如我所说的,例如:-如果I=4;那么rp[I]=rp[4]+rp[0],当I=8时用于下一次迭代;rp[8]=rp[8]+rp[4]作为rp[4]已更新,但在并行执行中并非如此。在并行执行中,我必须为每个工作项每次计算该值。例如:-rp[8]=rp[8]+rp[4]+rp[0]..溢出会被正确处理吗?为了安全起见,我会将int32作为临时值。@DarkZeros,如果我使用的测试包装生成了良好的覆盖率,那么这个版本与原始版本是等效的。另一方面,如您所建议的,使用int32很可能会提高性能并减少代码大小:.int32不能正常工作他的错误是将int32错误-45放入clCreateKernel子错误-48放入clsetkernelargs 1错误-48放入clsetkernelargs 2错误-48放入clsetkernelargs 3错误-48放入clsetkernelargs 4错误-48放入NDRANge
__kernel void subFilter(
    __global unsigned char  *rp,
    __global unsigned char  *out,
    int                     istop,
    int                     bpp)
{
    int gid = get_global_id(0), i = gid;
    unsigned char temp = 0;

    if(gid>=bpp){
        i=gid;

        while(i>=0)
        {
            if(temp > 255 - rp[i])
            {
                temp -= 255 - rp[i];
            }
            else
            {
                temp += rp[i];
            }

            i -= bpp;
        }

        //masked
        out[gid]=(temp & 0xff);  
    }
    else if(gid<bpp){
        out[gid]=rp[gid];
    }
}
__kernel void subFilter(__global unsigned char* rp,__global unsigned char *out,int istop,int bpp)
{
    int gid = get_global_id(0);//add the offset by bpp to access the next gid
    int i;
    unsigned char temp=0;

    out[gid]=rp[gid];
    if(gid>=bpp){
        i=gid;
        while(i>=0)
        {
            temp+=rp[i];
            i-=bpp;
        }
        out[gid]=(temp & 0xff);  //masked
    }
}