OpenMP, для цикла внутри секции - PullRequest
4 голосов
/ 27 октября 2011

Я хотел бы запустить следующий код (ниже).Я хочу создать два независимых потока, каждый из которых будет запускать параллельный цикл for.К сожалению, я получаю ошибку.По-видимому, параллельная for не может появляться внутри section.Как это решить?

#include <omp.h>
#include "stdio.h"

int main()
{

omp_set_num_threads(10);

#pragma omp parallel    
#pragma omp sections
  {
#pragma omp section
#pragma omp for
    for(int i=0; i<5; i++) {
        printf("x %d\n", i);
    }

#pragma omp section
#pragma omp for
    for(int i=0; i<5; i++) {
        printf(". %d\n", i);
    }
  } // end parallel and end sections
}

И ошибка:

main.cpp: In function ‘int main()’:
main.cpp:14:9: warning: work-sharing region may not be closely nested inside of work-sharing, critical, ordered, master or explicit task region [enabled by default]
main.cpp:20:9: warning: work-sharing region may not be closely nested inside of work-sharing, critical, ordered, master or explicit task region [enabled by default]

Ответы [ 3 ]

6 голосов
/ 27 октября 2011

Здесь вы должны использовать вложенный параллелизм.Проблема с omp for в sections заключается в том, что все потоки в области должны участвовать в omp for, а они явно не участвуют - они разбиты по разделам.Таким образом, вы должны ввести функции и выполнить вложенный параллелизм внутри функций.

#include <stdio.h>
#include <omp.h>

void doTask1(const int gtid) {
    omp_set_num_threads(5);
#pragma omp parallel 
    {
        int tid = omp_get_thread_num();
        #pragma omp for
        for(int i=0; i<5; i++) {
            printf("x %d %d %d\n", i, tid, gtid);
        }
    }
}

void doTask2(const int gtid) {
    omp_set_num_threads(5);
#pragma omp parallel 
    {
        int tid = omp_get_thread_num();
        #pragma omp for
        for(int i=0; i<5; i++) {
            printf(". %d %d %d\n", i, tid, gtid);
        }
    }
}


int main()
{
    omp_set_num_threads(2);
    omp_set_nested(1);

#pragma omp parallel    
    {
        int gtid = omp_get_thread_num();
#pragma omp sections
        {
#pragma omp section
            doTask1(gtid);

#pragma omp section
            doTask2(gtid);
        } // end parallel and end sections
    }
}
3 голосов
/ 27 октября 2011

OpenMP не может создавать параллельные области внутри параллельных областей.Это связано с тем, что OpenMP создает в начале программы num_threads параллельные потоки, в непараллельных регионах остальные не используются и спят.Они сделали это, так как частое создание новых потоков довольно медленное по сравнению с пробуждением спящих потоков.

Поэтому вы должны распараллеливать только циклы:

#include <omp.h>
#include "stdio.h"

int main()
{

omp_set_num_threads(10);

#pragma omp parallel for
    for(int i=0; i<5; i++) {
        printf("x %d\n", i);
    }

#pragma omp parallel for
    for(int i=0; i<5; i++) {
        printf(". %d\n", i);
    }
}
1 голос
/ 27 октября 2011

Практически оптимальное количество потоков равно количеству доступных процессорных ядер.Таким образом, каждая параллель для должна обрабатываться во всех доступных ядрах, что невозможно внутри omp секции .То, чего вы пытаетесь достичь, не является оптимальным.Предложение tune2fs выполнить два цикла без секций имеет смысл и дает наилучшую возможную производительность.Вы можете выполнять параллельные циклы внутри других функций, но этот «обман» не дает повышения производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...