OpenCL mandlebrot 图,在 GPU 上非常嘈杂

OpenCL mandlebrot plot, very noisy on GPU

为了尝试学习 OpenCL,我决定绘制 Mandlebrot 集的图。 它似乎在 CPU 上工作正常。下面的两张图片显示,第一个是在 CPU(Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz)上执行的内核,第二张图片显示的是在GPU(高清显卡 4000)。

这是内核:

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 上使用此功能。每次执行时,集合周围的噪声部分会略有(随机)变化。

我希望我已经提供了足够的信息,如果有人对可能存在的问题提出建议,我将很高兴听到!

谢谢:)

编辑

我做了以下事情:

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

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

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

看来噪声对迭代次数很敏感。

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

干杯

有时驱动程序在驱动程序端的矢量实现上存在错误。如果 fp64 支持或主机端元素对齐检查不起作用,则尝试 "scalar" 版本可以简单地解决它。

例如,我的 fx-8150 cpu 在 float8 和 float16 方面有问题,但 gpus 在任何原生矢量上都没有问题,在遥远的过去 fx-8150 也没有问题。也许我们被迫(无意或有意)购买新技术。

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

也许我错了,你的集成 GPU 快没电了。

代码在 GPU 上的 Windows 8.1 上使用适用于您的处理器类型的最新驱动程序,稍作修改(例如 (float)(PIXEL_WIDTH) 和 0.5f 等)即可正常运行,所以这表明 Mac.

上存在图形驱动程序问题