Openmp: невозможно правильно рассчитать статус задания внутри параллели для цикла

Я пытаюсь реализовать функции отчетности о состоянии задачи внутри параллельного цикла for. Это распараллеливание цикла for выполняется с использованием «OPENMP».

Я хочу, чтобы отчеты о состоянии выполнялись следующим образом:

Work done 70%; estimated time left 3:30:05 hour.

Конечно, я могу рассчитать «оставшееся время», вычислив разницу между «временем начала» и «текущим временем». Но, похоже, я не могу точно рассчитать «проделанную работу» внутри цикла for, даже используя «статическое» объявление.

Некоторое руководство будет оценено.

Вывод моего кода:

Values of cores : 8
Outer loop =================================
Thread 0  iCount0
% of work done 10
Outer loop =================================
Thread 0  iCount1
Outer loop =================================
Thread 2  iCount2
Outer loop =================================
Thread 7  iCount3
% of work done 40
Outer loop =================================
Thread 5  iCount4
% of work done 50
Outer loop =================================
Thread 3  iCount5
% of work done 60
Outer loop =================================
Thread 4  iCount6
% of work done 70
Outer loop =================================
Thread 1  iCount7
% of work done 20
% of work done 80
Outer loop =================================
Thread 6  iCount8
% of work done 90
Outer loop =================================
Thread 1  iCount9
% of work done 100
% of work done 30

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

Вот мой код:

ПРИМЕЧАНИЕ: я намеренно использовал «std :: endl», а не «\ n», поскольку каким-то образом очистка выходного буфера портит мой расчет% работы. Я уверен, что подобный сценарий возникнет, если я выполню реальные вычисления внутри параллельной

#include "stdafx.h"#include <iostream>     // std::cout, std::endl
#include <iomanip>      // std::setfill, std::setw
#include <math.h>       /* pow */
#include <omp.h>

int main(int argc, char** argv)
{
// Get the number of processors in this system
int iCPU = omp_get_num_procs();

// Now set the number of threads
omp_set_num_threads(iCPU);
std::cout << "Values of cores : " << iCPU <<" \n";

int x = 0;
int iTotalOuter = 10;
static int iCount = 0;

#pragma omp parallel for private(x)
for(int y = 0; y < iTotalOuter; y++)
{
std::cout << "Outer loop =================================\n" ;
std::cout <<"\nThread "<<omp_get_thread_num()<<"  iCount" << iCount<<std::endl;

for(x = 0; x< 5; x++)
{
//std::cout << "Inner loop \n" ;
}
iCount = iCount + 1;
std::cout <<"\n % of work done " << (double)100*((double)iCount/(double)iTotalOuter)<<std::endl;
}

std::cin.ignore(); //Wait for user to hit enter
return 0;
}

ОБНОВИТЬ:
Основываясь на ответе «Ави Гинзбурга», я пытаюсь сделать так:

#include "stdafx.h"#include <iostream>     // std::cout, std::endl
#include <iomanip>      // std::setfill, std::setw
#include <math.h>       /* pow */
#include <omp.h>
void ReportJobStatus(int , int );

int main(int argc, char** argv)
{
// Get the number of processors in this system
int iCPU = omp_get_num_procs();

// Now set the number of threads
omp_set_num_threads(iCPU);
std::cout << "Values of cores : " << iCPU <<" \n";

int x = 0;
int iTotalOuter = 100;
static int iCount = 0;

#pragma omp parallel for private(x)
for(int y = 0; y < iTotalOuter; y++)
{
std::cout << "Outer loop =================================\n" ;

for(x = 0; x< 5; x++)
{
//std::cout << "Inner loop \n" ;
}
#pragma omp atomic
iCount++;

std::cout<< " omp_get_thread_num(): " << omp_get_thread_num() <<"\n";
if (omp_get_thread_num() == 0){
ReportJobStatus(iCount, iTotalOuter);
}

}

std::cin.ignore(); //Wait for user to hit enter
return 0;
}

Проблема (Обновлено): Проблема в том, что один и тот же поток используется для одновременного выполнения. Таким образом, отчет о проделанной работе становится серьезно ограниченным. Как можно назначать задания различным ядрам на основе данных.

Вот текущий вывод моего кода:

Outer loop =================================
omp_get_thread_num(): 0

% of work done 1
Outer loop =================================
omp_get_thread_num(): 0

% of work done 2
Outer loop =================================
omp_get_thread_num(): 0

% of work done 3
Outer loop =================================
omp_get_thread_num(): 0

% of work done 4
Outer loop =================================
omp_get_thread_num(): 0

% of work done 5
Outer loop =================================
omp_get_thread_num(): 0

% of work done 6
Outer loop =================================
omp_get_thread_num(): 0

% of work done 7
Outer loop =================================
omp_get_thread_num(): 0

% of work done 8
Outer loop =================================
omp_get_thread_num(): 0

% of work done 9
Outer loop =================================
omp_get_thread_num(): 0

% of work done 10
Outer loop =================================
omp_get_thread_num(): 0

% of work done 11
Outer loop =================================
omp_get_thread_num(): 0

% of work done 12
Outer loop =================================
omp_get_thread_num(): 0

% of work done 13
Outer loop =================================
omp_get_thread_num(): 0

% of work done 14
Outer loop =================================
omp_get_thread_num(): 0

% of work done 15
Outer loop =================================
omp_get_thread_num(): 0

% of work done 16
Outer loop =================================
omp_get_thread_num(): 0

% of work done 17
Outer loop =================================
omp_get_thread_num(): 0

% of work done 18
Outer loop =================================
omp_get_thread_num(): 0
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 1

% of work done 19
Outer loop =================================
omp_get_thread_num(): 0

% of work done 54
Outer loop =================================
omp_get_thread_num(): 0

% of work done 55
Outer loop =================================
omp_get_thread_num(): 0

% of work done 56
Outer loop =================================
omp_get_thread_num(): 0

% of work done 57
Outer loop =================================
omp_get_thread_num(): 0

% of work done 58
Outer loop =================================
omp_get_thread_num(): 0

% of work done 59
Outer loop =================================
omp_get_thread_num(): 0

% of work done 60
Outer loop =================================
omp_get_thread_num(): 0

% of work done 61
Outer loop =================================
omp_get_thread_num(): 0

% of work done 62
Outer loop =================================
omp_get_thread_num(): 6
Outer loop =================================
omp_get_thread_num(): 6
Outer loop =================================
omp_get_thread_num(): 6
Outer loop =================================
omp_get_thread_num(): 6
Outer loop =================================
omp_get_thread_num(): 6
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 3
Outer loop =================================
omp_get_thread_num(): 1
Outer loop =================================
omp_get_thread_num(): 5
Outer loop =================================
omp_get_thread_num(): 5
Outer loop =================================
omp_get_thread_num(): 5
Outer loop =================================
omp_get_thread_num(): 5
Outer loop =================================
omp_get_thread_num(): 5
Outer loop =================================
omp_get_thread_num(): 5
Outer loop =================================
omp_get_thread_num(): 5
Outer loop =================================
omp_get_thread_num(): 5
Outer loop =================================
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
Outer loop =================================
omp_get_thread_num(): 4
omp_get_thread_num(): 7
Outer loop =================================
omp_get_thread_num(): 7
Outer loop =================================
omp_get_thread_num(): 7
Outer loop =================================
omp_get_thread_num(): 7
Outer loop =================================
omp_get_thread_num(): 7
Outer loop =================================
omp_get_thread_num(): 7
Outer loop =================================
omp_get_thread_num(): 2
Outer loop =================================
omp_get_thread_num(): 2
Outer loop =================================
omp_get_thread_num(): 2
Outer loop =================================
omp_get_thread_num(): 2
Outer loop =================================
omp_get_thread_num(): 2
Outer loop =================================
omp_get_thread_num(): 2
Outer loop =================================
omp_get_thread_num(): 2

1

Решение

Использовать critical или же atomic в цикле:

#pragma omp critical
{
(++prog);
}

или лучше:

#pragma omp atomic
(++prog);

и думать только о том, чтобы позволить главному потоку распечатать прогресс.

if(omp_get_thread_num() == 0)
{
cout << "Progress: " << float(prog)/totalNumber;
}
4

Другие решения


По вопросам рекламы [email protected]