OpenCL для цикла делает странные вещи - PullRequest
0 голосов
/ 07 ноября 2011

В настоящее время я реализую генерацию рельефа в 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, приводя к проблемам с синхронизацией, или япропустить что-то еще?

Любая помощь приветствуется!

Ответы [ 2 ]

3 голосов
/ 08 ноября 2011

проблема вашего кода в строках

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

, вскоре "постоянство" превысит предел для float, и вы получите нули (или неопределенное поведение) в вашем ответе.

РЕДАКТИРОВАТЬ Еще две вещи

  1. Накопление (реализация 2) не очень хорошая идея, особенно с действительными числами и с алгоритмами, которые требуют точности.Возможно, вы теряете небольшую часть своей информации каждый раз, когда накапливаете «постоянство» (например, из-за округления).Предпочитайте прямые вычисления (1-е внедрение), а не накопление, когда вы можете.(плюс, если бы это был Serial, реализация 2 будет легко распараллеливаемой.)
  2. Если вы работаете с AMD OpenCL, обратите внимание на функции pow ().У меня были проблемы с ними на нескольких машинах несколько раз.Функции, кажется, зависают иногда без причины.Просто к вашему сведению.
1 голос
/ 07 ноября 2011

Я предполагаю, что это какой-то служебный метод, который вызывается в вашем ядре CL. Вивек прав в своем комментарии выше: OpenCL не распараллеливает ваш код для вас. Вы должны использовать возможности OpenCL для разделения вашей проблемы на куски, параллельные данным.

Кроме того, я не вижу потенциальной проблемы синхронизации в приведенном выше коде. Все ваши переменные находятся в пространстве личной памяти рабочего элемента.

...