OpenMP планировщик - добиться равномерного распределения задач - C (СИ)
Формулировка задачи:
Есть следующий код:
Чтобы не делал на выходе получаю cnt1 = 1, а cnt2 = 59.
Не могу понять почему так происходит. Есть предположение что планировщик OpenMP работает по принципу LIFO. Соответственно цикл успевает сделать вторую итерацию пока первая таска не выполнилась и запустить вторую и так далее. В итоге начнутся выполняться с конца.
Может я не прав и проблема в другом?
#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;
}Решение задачи: «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.
- В первой строке объявлены переменные i, cnt1 и cnt2.
- Затем следует директива #pragma omp parallel for shared(i, cnt1, cnt2), которая создает параллельный цикл for для переменных i от 0 до 60. Переменные i, cnt1 и cnt2 разделяются между параллельными потоками.
- Внутри цикла if-else происходит инкремент одной из переменных cnt1 или cnt2.
- Если значение cnt1 меньше значения cnt2, то выполняется инкремент cnt1.
- Если значение cnt1 больше или равно значению cnt2, то выполняется инкремент cnt2.
- После завершения цикла, выводится значение переменных cnt1 и cnt2 с помощью функции printf.
- В конце программы возвращается 0, что означает успешное завершение программы. Код пытается выровнять нагрузку между cnt1 и cnt2, путем инкремента одной переменной в каждом потоке. Однако, так как значения cnt1 и cnt2 не сбрасываются перед началом программы, результат может быть непредсказуемым.