OpenMP планировщик - добиться равномерного распределения задач - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Есть следующий код:
#include <stdio.h>
#include <unistd.h>
 
int cnttotal = 0;
int cnt1 = 0, cnt2 = 0;
 
int main()
{
    int i;
    #pragma omp parallel
    #pragma omp single nowait
    for (i = 0; i < 60; i++) {
        if (cnttotal < 1) {
            cnttotal++;
            #pragma omp task
            {
                #pragma omp atomic
                cnt1++;
                usleep(10);
                cnttotal--;
            }
        } else {
            #pragma omp task
            {
                #pragma omp atomic
                cnt2++;
                sleep(1);
            }
        }
    }
 
printf("cnt1 = %d; cnt2 = %d\n", cnt1, cnt2);
 
    return 0;
}
Чтобы не делал на выходе получаю cnt1 = 1, а cnt2 = 59. Не могу понять почему так происходит. Есть предположение что планировщик OpenMP работает по принципу LIFO. Соответственно цикл успевает сделать вторую итерацию пока первая таска не выполнилась и запустить вторую и так далее. В итоге начнутся выполняться с конца. Может я не прав и проблема в другом?

Решение задачи: «OpenMP планировщик - добиться равномерного распределения задач»

textual
Листинг программы
#include <stdio.h>
 
int main() {
    int i, cnt1 = 0, cnt2 = 0;
 
    #pragma omp parallel for shared(i, cnt1, cnt2)
    for (i = 0; i < 60; i++) {
        if (cnt1 < cnt2) {
            #pragma omp atomic
            cnt1++;
        }
        else {
            #pragma omp atomic
            cnt2++;
        }
    }
 
    printf("cnt1 = %d, cnt2 = %d\n", cnt1, cnt2);
 
    return 0;
}

Объяснение кода листинга программы

В данном коде используется OpenMP для параллельных вычислений. Целью программы является выравнивание нагрузки между двумя переменными cnt1 и cnt2.

  1. В первой строке объявлены переменные i, cnt1 и cnt2.
  2. Затем следует директива #pragma omp parallel for shared(i, cnt1, cnt2), которая создает параллельный цикл for для переменных i от 0 до 60. Переменные i, cnt1 и cnt2 разделяются между параллельными потоками.
  3. Внутри цикла if-else происходит инкремент одной из переменных cnt1 или cnt2.
  4. Если значение cnt1 меньше значения cnt2, то выполняется инкремент cnt1.
  5. Если значение cnt1 больше или равно значению cnt2, то выполняется инкремент cnt2.
  6. После завершения цикла, выводится значение переменных cnt1 и cnt2 с помощью функции printf.
  7. В конце программы возвращается 0, что означает успешное завершение программы. Код пытается выровнять нагрузку между cnt1 и cnt2, путем инкремента одной переменной в каждом потоке. Однако, так как значения cnt1 и cnt2 не сбрасываются перед началом программы, результат может быть непредсказуемым.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.875 из 5
Похожие ответы