0

我目前正在使用分层八度音阶在 OpenCL 中实现地形生成,我偶然发现了这个问题:

float multinoise2d(float2 position, float scale, int octaves, float persistence)
{
    float result = 0.0f;
    float sample = 0.0f;
    float coefficient = 1.0f;

    for(int i = 0; i < octaves; i++){
        // get a sample of a simple signed perlin noise
        sample = sgnoise2d(position/scale);

        if(i > 0){
            // Here is the problem:

            // Implementation A, this works correctly.
            coefficient = pown(persistence, i);

            // Implementation B, using this only the first
            // noise octave is visible in the terrain.
            coefficient = persistence;
            persistence = persistence*persistence;
        }

        result += coefficient * sample;
        scale /= 2.0f;
    }
    return result;
}

OpenCL 是否会并行化 for 循环,从而导致此处出现同步问题,或者我是否遗漏了其他内容?

任何帮助表示赞赏!

4

2 回答 2

3

您的代码的问题在于行

coefficient = persistence;
persistence = persistence*persistence;

应该改为

coefficient = coefficient *persistence;

否则在每次迭代

第一个系数仅靠坚持而增长

pow(persistence, 1) ; pow(persistence, 2); pow(persistence, 3) ....

然而,第二个实现去

pow(persistence, 1); pow(persistence, 2); pow(persistence, 4); pow(persistence, 8) ......

很快,“持久性”将超过浮点数的限制,您的答案将得到零(或未定义的行为)。

编辑还有两件事

  1. 累加(实现 2)不是一个好主意,特别是对于实数和需要准确性的算法。每次累积“持久性”(例如由于四舍五入)时,您可能会丢失一小部分信息。尽可能选择直接计算(第一次实现)而不是累积。(加上如果这是串行的,第二个实现将很容易并行化。)
  2. 如果您使用 AMD OpenCL,请注意 pow() 函数。我曾多次在多台机器上遇到过问题。这些功能有时似乎无缘无故挂起。仅供参考。
于 2011-11-07T21:52:14.737 回答
1

我假设这是在您的 CL 内核中调用的某种实用程序方法。Vivek 在上面的评论中是正确的:OpenCL 不会为您并行化您的代码。您必须利用 OpenCL 的工具将您的问题划分为数据并行块。

另外,我在上面的代码中没有看到潜在的同步问题。您的所有变量都在工作项私有内存空间中。

于 2011-11-07T18:45:04.713 回答