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) ....

ただし、2番目の実装は

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

間もなく「永続性」がfloatの制限を超えて実行され、回答にゼロ(または未定義の動作)が含まれるようになります。

編集あと2つ

  1. 累積(実装2)は、特に実数や精度を必要とするアルゴリズムではお勧めできません。「永続性」を蓄積するたびに(たとえば、丸めのために)、情報のごく一部が失われる可能性があります。可能な限り、累積よりも直接計算(最初の実装)を優先します。(さらに、これがシリアルの場合、2番目の実装は容易に並列化できます。)
  2. AMD OpenCLを使用している場合は、pow()関数に注意してください。複数のマシンで何度も問題が発生しました。理由もなく機能がハングすることがあります。参考までに。
于 2011-11-07T21:52:14.737 に答える