Количество работающих потоков меньше, чем ожидается C++ OpenMP
У меня возникла следующая проблема: я пытаюсь задать 4 потока в параллельных областях, однако вижу, что работает только 2. Прим. Переменные A,B,X,previousX - {vector<vector>(MxM), vector(M) , vector(M), vector(M)} соответственно. Делал в Visual Studio. Пример кода:
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <iostream>
#include <string>
#include <vector>
#include <omp.h>
#include <cmath>
using namespace std;
//ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ (входные данные)
int M = 3;
double E = 0.001;
vector<double> B{ 8,10,15 };
vector<vector<double>> A
{
{3,1,1},
{1,3,1},
{1,2,5}
};
int main()
{
setlocale(0, "");
vector<double> X(B);
vector<double> previousX(X);
double sum = 0;
printf("ПРИМЕР, в котором всё в порядке и работает как надо (работает 4 потока):\n");
#pragma omp parallel for reduction(+:sum) num_threads(4) schedule(static,1)
for (int i = 0; i < 10; ++i)
{
Sleep(100);
sum += 2;
printf("Работает нить %d\n", omp_get_thread_num());
}
printf("sum = %lf\n", sum);
printf("конец ПРИМЕРА\n");
printf("===========================================\n");
//omp_set_nested(0);
printf("Начало работы алгоритма:\n");
double start_time = omp_get_wtime();
int iterCount = 0;
while (true)
{
printf("Текущая итерация №%d\n", iterCount);
for (int i = 0; i < M; ++i)
{
double sum1 = 0;
double sum2 = 0;
#pragma omp parallel for reduction(+:sum1) schedule(static,1) num_threads(4) shared(A,B,X,previousX)
for (int j = 0; j <= i - 1; ++j)
{
sum1 += A[i][j] / A[i][i] * X[j];
Sleep(100);
printf("Работает нить %d\n", omp_get_thread_num());
}
#pragma omp parallel for reduction(+:sum2) schedule(static,1) num_threads(4) shared(A,B,X,previousX)
for (int j = i + 1; j <= M - 1; ++j)
{
sum2 += A[i][j] / A[i][i] * X[j];
Sleep(100);
printf("Работает нить %d\n", omp_get_thread_num());
}
previousX[i] = X[i];
X[i] = B[i] / A[i][i] - sum1 - sum2;
}
double max = -1;
for (int i = 0; i < M; ++i)
{
if (max < abs(X[i] - previousX[i]))
{
max = abs(X[i] - previousX[i]);
}
}
if (max < E)
break;
iterCount++;
}
double end_time = omp_get_wtime();
printf("Количество итераций: %d\n", iterCount);
printf("Время выполнения: %lf\n", end_time - start_time);
printf("Конец работы алгоритма\n");
}
В результате я вижу на экране, что работают нити 0 и 1.
Для примера input2_00 будет такой вывод (не до конца, конечно, но проблему там можно увидеть, наверное)

Я предварительно прогонял обычные примеры, как, например, этот
double sum = 0;
#pragma omp parallel for reduction(+:sum) num_threads(4) schedule(static,1)
for (int i = 0; i < 10; ++i)
{
Sleep(100);
sum += 2;
printf("Работает нить %d\n", omp_get_thread_num());
}
printf("sum = %lf", sum);
И в этом просто "тесте" всё работает, как надо, и я вижу, что работают все 4 потока. Подскажите, пожалуйста, что за ошибку я допустил?
Ответы (1 шт):
Пользователь @Fat-Zer подсказал в чём проблема! Большое спасибо! Я не принял во внимание, что количество итераций для распараллеливания крайне мало. В данном случае
дык, матрица всего 3×3... на первый цикл приходится всего 2 итерации, а на второй — одна... или наоборот... вот и не хватает на 3 процесса всё это разнести... - Far-Zer.
То есть по существу проблемы тут нет. Всё лишь моя невнимательность и невежество.
Надеюсь этот вопрос будет кому-то полезен:)