Вопрос по set, multithreading, c++, openmp, numbers – OpenMP set_num_threads () не работает

25

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

Я хочу контролировать количество потоков в программе, используя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

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

Ваш Ответ

5   ответов
78

Помимо звонкаomp_get_num_threads() за пределами параллельной области в вашем случае, звоняomp_set_num_threads() все еще не гарантирует, что среда выполнения OpenMP будет использовать точно указанное количество потоков.omp_set_num_threads() используется для переопределения значения переменной средыOMP_NUM_THREADS и они оба контролируютupper limit размера команды потока, которую 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 ...
}
Во-первых,serial версия занимает 50 мс на моем процессоре. Вы не можете ожидать ускорения для таких быстрых кодов из-за издержек OpenMP. Поместите в цикл в 100 раз больше взаимодействий. Во-вторых, вы пропали без вестиparallel регион в вашем исходном коде. Ты написал#pragma omp for ... в то время как это должно быть#pragma omp parallel for ..., В-третьих, вы смешиваете MPI и OpenMP. Вы уверены, что точно знаете, что делаете?
@HristoIliev Может ли пользователь динамически контролировать количество потоков? т.е. вместо использования жестко закодированных4, использовать переменную?
@ OmarHaque, да,num_threads Предложение также принимает переменные, так что можно контролировать количество потоков во время выполнения.
Но я не смог получить никакого ускорения, изменив количество потоков, а также установив omp_set_dynamic (0) ?? Nurlan
@ Manatttta, да. Значение передается в библиотеку времени выполнения OpenMP каждый раз, когда во время выполнения программы встречается параллельная область, поэтому использование переменной работает, как и ожидалось.
0

Попробуйте установить ваши num_threads в вашем параллельном коде, это работает для меня. Это даст выход как 4

#pragma omp parallel
{
   omp_set_num_threads(4);
   int id = omp_get_num_threads();
   #pragma omp for
   for (i = 0:n){foo(A);}
}

printf("Number of threads: %d", id);
17

omp_get_num_threads() функция возвращает количество потоков, которыеcurrently in the team executing the parallel region from which it is called, Вы называете это за пределами параллельной области, именно поэтому это возвращает1.

2

Я столкнулся с той же проблемой. Решение приведено ниже

Нажмите правой кнопкой мыши на Исходную программу & gt; Свойства & gt; Свойства конфигурации & gt; C / C ++ & gt; Язык & gt; Теперь измените флаг поддержки Open MP на Yes ....

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

4

СогласноРуководство GCC для omp_get_num_threads:

In a sequential section of the program omp_get_num_threads returns 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;
}

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

Похожие вопросы