Подтвердить что ты не робот

OpenMP set_num_threads() не работает

Я пишу параллельную программу, использующую OpenMP в С++.

Я хочу контролировать количество потоков в программе с помощью omp_set_num_threads(), но это не работает.

#include <iostream>
#include <omp.h>
#include "mpi.h"

using namespace std;

int myrank;
int groupsize;
double sum;
double t1,t2;
int n = 10000000;

int main(int argc, char *argv[])
{
    MPI_Init( &argc, &argv);
    MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
    MPI_Comm_size(MPI_COMM_WORLD,&groupsize);

    omp_set_num_threads(4);

    sum = 0;
    #pragma omp for  reduction(+:sum)
    for (int i = 0; i < n; i++)
        sum+= i/(n/10);

    cout<<"sum="<<sum<<endl;
    cout<<"threads="<<omp_get_num_threads()<<endl;

    MPI_Finalize();
    return 0;
}

Выходы программы:

sum = 4.5e+007
threads=1

Как контролировать количество потоков?

4b9b3361

Ответ 1

Помимо вызова omp_get_num_threads() за пределами параллельной области в вашем случае вызов omp_set_num_threads() по-прежнему не гарантирует, что среда выполнения OpenMP будет использовать точно указанное количество потоков. omp_set_num_threads() используется для переопределения значения переменной окружения OMP_NUM_THREADS, и оба они контролируют верхний предел размера команды потока, который OpenMP будет появляться для всех параллельных областей (в случае OMP_NUM_THREADS) или для любого (после вызова omp_set_num_threads()). Есть что-то называемое динамическими командами, которые все еще могут выбирать меньшее количество потоков, если система времени выполнения считает это более подходящим. Вы можете отключить динамические команды, вызвав omp_set_dynamic(0) или установив переменную окружения OMP_DYNAMIC на false.

Чтобы обеспечить заданное количество потоков, вы должны отключить динамические команды и указать нужное количество потоков с помощью omp_set_num_threads():

omp_set_dynamic(0);     // Explicitly disable dynamic teams
omp_set_num_threads(4); // Use 4 threads for all consecutive parallel regions
#pragma omp parallel ...
{
    ... 4 threads used here ...
}

или с предложением num_threads OpenMP:

omp_set_dynamic(0);     // Explicitly disable dynamic teams
// Spawn 4 threads for this parallel region only
#pragma omp parallel ... num_threads(4)
{
    ... 4 threads used here ...
}

Ответ 2

Функция omp_get_num_threads() возвращает количество потоков, которые в настоящее время находятся в команде, выполняющей параллельную область, из которой она вызывается. Вы вызываете его за пределами параллельной области, поэтому он возвращает 1.

Ответ 3

В соответствии с руководство GCC для omp_get_num_threads:

В последовательном разделе программы omp_get_num_threads возвращает 1

Итак, это:

cout<<"sum="<<sum<<endl;
cout<<"threads="<<omp_get_num_threads()<<endl;

Должно быть изменено на что-то вроде:

#pragma omp parallel
{
    cout<<"sum="<<sum<<endl;
    cout<<"threads="<<omp_get_num_threads()<<endl;
}

Код, который я использую, также содержит рекомендации для отключения динамических команд.

Ответ 4

У меня была та же проблема. Решение приведено ниже

Щелкните правой кнопкой мыши на исходной программе > Свойствa > Свойства конфигурации > C/С++ > Язык > Теперь измените флаг поддержки поддержки MP на Да....

Вы получите желаемый результат.