c++ - 设置主机和执行功能有什么区别?

标签 c++ opencl

我正在尝试使用 Opencl 制作卷积图像。

__kernel void convolution_read4(__global uchar *in1, __global uchar* in2,
__constant float* mask, int  height,  int  width,  int  kernelSize,
__local float* lMem, int  localHeight, int  localWidth)
{
    convolution(in1, in2, mask, height, width, kernelSize, lMem, localHeight, localWidth);
    convolution(in2, in1, mask, height, width, kernelSize, lMem, localHeight, localWidth);
    convolution(in1, in2, mask, height, width, kernelSize, lMem, localHeight, localWidth);
}

上层代码执行同一个函数3次。

    err = kernel.setArg(0, d_inputImage);
    err |= kernel.setArg(1, d_outputImage);
    err |= kernel.setArg(2, d_filter);
    err |= kernel.setArg(3, Height);
    err |= kernel.setArg(4, Width);     
    err |= kernel.setArg(5, kernelSize);
    err |= kernel.setArg(6, localSize, NULL);
    err |= kernel.setArg(7, localHeight);
    err |= kernel.setArg(8, localWidth);        

    int totalWorkItemX = roundUp(Width - paddingPixels, wgWidth);
    int totalWorkItemY = roundUp(Height - paddingPixels , wgHeight);

    cl::NDRange globalws(totalWorkItemX, totalWorkItemY);
    cl::NDRange localws(wgWidth, wgHeight);

    err = queue.enqueueNDRangeKernel(kernel, cl::NullRange,
        globalws, localws, NULL, NULL);

    err = kernel.setArg(1, d_inputImage);
    err |= kernel.setArg(0, d_outputImage);
    err = queue.enqueueNDRangeKernel(kernel, cl::NullRange,
        globalws, localws, NULL, NULL);

    err = kernel.setArg(0, d_inputImage);
    err |= kernel.setArg(1, d_outputImage);
    err = queue.enqueueNDRangeKernel(kernel, cl::NullRange,
        globalws, localws, NULL, NULL);

    queue.finish();

此代码也执行相同的函数“Convolution”,但内核代码已更改为那样。

__kernel void convolution_read4(__global uchar *in1, __global uchar* in2,
    __constant float* mask, int  height,  int  width,  int  kernelSize,
    __local float* lMem, int  localHeight, int  localWidth)
    {
        convolution(in1, in2, mask, height, width, kernelSize, lMem, localHeight, localWidth);                  
    }

我认为这两个代码是相同的代码。但是第一个代码得出了错误的输出。 我不知道这两者有什么区别。

最佳答案

您的卷积 函数可能会从全局内存中获取整个输入图像,并在全局内存中生成整个输出图像。在单个内核调用中调用此函数三次与从三个单独的内核调用中调用一次之间的区别在于,一个工作项对全局内存的写入对于同一内核调用中的其他工作项是不可见的。这意味着在您的第一个示例中第二次调用 convolution 期间,工作项将读取陈旧值,并且看不到第一次调用此函数的输出。

OpenCL 不提供任何方式来同步整个内核调用中的全局内存。您可以使用 barrier 函数同步工作组内的内存,这可能允许您在单个内核调用中实现您的算法,并进行一些修改。

关于c++ - 设置主机和执行功能有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26237678/

相关文章:

java - 内存分配 - Java 与 C++

c++ - 有没有办法保存自动变量并在以后使用它?

c - opencl在内核中迭代数组

OpenCL 全局内存获取

c++ - 设置 Qt Widget 掩码

c++ - 单例模式的延迟初始化

c++ - 不匹配 C++ 中的 operator+ 错误

c - OpenCL clEnqueueReadBuffer 段错误随机

ios - Apple Metal Matrix 乘法基准测试结果不一致

opencl - OpenCL 应用程序中的多个程序(与内核)