OpenCL mandlebrot情节,在GPU上非常嘈杂

时间:2016-02-20 20:10:58

标签: c++ opencl gpgpu

在尝试学习OpenCL时,我决定制作Mandlebrot套装的情节。 它似乎工作正常,在CPU上。下面的两张图显示了首先在CPU上执行的内核(Intel(R)Core(TM)i5-3210M CPU @ 2.50GHz),第二张图像显示了在GPU(HD Graphics 4000)上渲染时的图像。 / p>

这是内核:

typedef float2 Complex;

Complex complex_mul(Complex a, Complex b) 
{
    return (Complex)(a.s0*b.s0-a.s1*b.s1, a.s1*b.s0+a.s0*b.s1);
}

__kernel 
void mandelbrot (__global float* p)
{
    const int x = get_global_id (0);
    const int y = get_global_id (1);
    const int arrlen = PIXELS_WIDTH * PIXELS_HEIGHT;


    float width = PIXELS_WIDTH;
    float height = PIXELS_HEIGHT;

    float whRatio = width / height;

    float tx = x;
    float ty = y;

    float px = ((tx / float(PIXELS_WIDTH)) - 0.5) * 2.0;
    float py = ((ty / float(PIXELS_HEIGHT)) - 0.5) * 2.0 / whRatio;

    Complex z;
    z.s0 = 0;
    z.s1 = 0;
    Complex c;
    c.s0 = px;
    c.s1 = py;


    float color = 0.0;

    int iterations = 500;
    for (int i = 0; i < iterations; i++)
    {
        z = complex_mul(z,z) + c;

        if ( length(z) > 2.0)
        {
            float u,o;
            u = i;
            o = iterations;
            color = ( u / o );
            break;
        }
    }


    const int pId =  y * PIXELS_WIDTH + x;
    if ( pId < arrlen )
    {
        p[ pId ] = color;
    }
}

主持人计划......至少是有趣的一点(我希望):

size_t globalSizes[2] = { PIXEL_WIDTH, PIXEL_HEIGHT };

cl_mem image_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(image_data), NULL, &error);
CheckError(error);

error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &image_buffer);
CheckError(error);

error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, globalSizes, NULL, 0, NULL, &computeDone); 
CheckError(error);

clWaitForEvents(1, &computeDone);

error = clEnqueueReadBuffer(queue, image_buffer, CL_TRUE, 0, sizeof(image_data), image_data, 0, NULL, NULL);
CheckError(error);

clReleaseMemObject(image_buffer);

我在OS X 10.9.5的MacBook Pro上运行。每次执行时,集合周围的噪声部分会稍微(随机)变化。

我希望我提供了足够的信息,如果有人对可能出错的地方有任何建议,我会很高兴听到!

谢谢:)

enter image description here

enter image description here

修改

我做了以下事情:

根据评论中的huseyin tugrul buyukisik的建议,将所有数字文字更改为浮点数。

然后将length(z) > 2.0更改为(z.s0 * z.s0) + (z.s1 * z.s1) > 4.0f

然后尝试使用迭代计数器。

噪声似乎对迭代次数非常敏感。

例如,1000次迭代会产生非常多的噪声,但1009次迭代会产生非常平滑的图像。有关为什么会发生这种情况的任何建议?

干杯

2 个答案:

答案 0 :(得分:0)

有时驱动程序在驱动程序端的向量实现上存在错误。如果fp64支持或主机端元素对齐检查不起作用,尝试“标量”版本只需解决它。

例如,我的fx-8150 cpu与float8和float16有问题,但是gpus对于任何原生载体都没问题,并且在遥远的过去没有fx-8150的问题。也许我们被迫(无意或有意)购买新技术。

您应该尝试不同版本的驱动程序,因为有时公司会故意或意外地调整设置并损坏支持列表。

也许我错了,你的集成gpu正在死亡。

答案 1 :(得分:0)

代码适用于使用适用于您的处理器类型的最新驱动程序在GPU上的Windows 8.1上进行微小修改(例如(浮点)(PIXEL_WIDTH)和0.5f等),因此这表明Mac上存在图形驱动程序问题。