Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
forks
0 / 0 / 0
Регистрация: 20.08.2016
Сообщений: 16
#1

Распараллеливание цикла For с использованием OpenMP - C++

31.10.2017, 14:19. Просмотров 252. Ответов 4
Метки нет (Все метки)

Всем привет. Задался целью изучить OpenMP, что бы в дальнейшем уметь распараллеливать программы.
Собственно, хочу распаралеллить цикл вот такого вида:
C++
1
2
3
for (i = 100; i <= 67899; i++)
    {
        if (i == 67887) {printf("kkk");}}
Нашёл вот такую статью по OpenMP: https://software.intel.com/ru-ru/blogs/2011/11/21/openmp-c
от туда решил взять самый последний пример в качестве опорного:
http://www.cyberforum.ru/cpp-beginners/thread1019659.html
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma omp for ordered schedule(dynamic)
 
 for(int n=0; n<100; ++n)
 
 {
 
   files[n].compress();
 
 
   #pragma omp ordered
 
   send(files[n]);
 
 }
Получил вот такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma omp for ordered schedule(dynamic)
 
    
 
 
    for (i = 100; i <= 67899; i++)
    {
 
        if (i == 67887) {
#pragma omp ordered
            printf("kkk");
        };
    }
При сборке получаю следующие ошибки:
Кликните здесь для просмотра всего текста

Серьезность Код Описание Проект Файл Строка Состояние подавления
Ошибка C3015 неверный вид инициализации в операторе For директивы OpenMP

Кликните здесь для просмотра всего текста

Серьезность Код Описание Проект Файл Строка Состояние подавления
Ошибка C3017 неверный вид проверки завершения в операторе For директивы OpenMP

Кликните здесь для просмотра всего текста
Серьезность Код Описание Проект Файл Строка Состояние подавления
Ошибка C3019 неверный вид приращения в операторе For директивы OpenMP

Кликните здесь для просмотра всего текста
Серьезность Код Описание Проект Файл Строка Состояние подавления
Ошибка C1903 не удается восстановить после предыдущих ошибок; остановка компиляции


Если тупо распараллелить весь цикл for, с указанием 4-х потоков, то printf срабатывает два раза (и то я так понимаю могло быть и больше раз), а должен всего один.

Подскажите как правильно распаралеллить этот цикл с использованием OpenMP, что бы сам цикл прогонялся на всех доступных ядрах CPU, и при этом условие IF так же выполнялось корректно, так же не в один поток, иначе смысла в распараллеливании самого цикла FOR не будет.

Добавлено через 2 минуты
Да, ещё забыл уточнить, что сам цикл не обязательно до конца прогонять, после нахождения искомого числа, по сути это мелочь. Планирую останавливать цикл с помощью оператора break.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.10.2017, 14:19
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Распараллеливание цикла For с использованием OpenMP (C++):

Распараллеливание с помощью OpenMP
Здравствуйте, уважаемые участники форума! Имеется цикл вида:for (i=1;...

Распараллеливание циклов с ипользованием OpenMP
Есть проблема , получился парадокс - время роботы программы с ...

Как выполнить распараллеливание с помощью OpenMP
Доброго дня. У меня есть две функции. void A(const vector &lt;double&gt; &amp;a){...

Распараллеливание вычисления интеграла используя редукции (OpenMP)
Доброго времени суток, ребята! Ксть задача распараллелить процесс вычисления...

Для распараллеливание процессов лучше пользоваться OpenMP или Win32?
Для распараллеливание процессов лучше пользоваться OpenMP или Win32? ...

4
mat_for_c
210 / 205 / 76
Регистрация: 26.04.2013
Сообщений: 957
Завершенные тесты: 3
31.10.2017, 14:26 #2
вам достаточно написать
C++
1
2
3
4
5
#pragma omp parallel for
for (i = 100; i <= 67899; i++) {
   if (i == 67887)
      printf("kkk");
}
Добавлено через 6 минут
Цитата Сообщение от forks Посмотреть сообщение
Планирую останавливать цикл с помощью оператора break
И да, omp parallel for не любит работать с break в цикле
0
forks
0 / 0 / 0
Регистрация: 20.08.2016
Сообщений: 16
31.10.2017, 14:54  [ТС] #3
Благодарю за ответ. Как же тогда останавливать цикл при использовании OpenMP?
И ещё такой важный момент, совместно с OpenMP хочу использовать библиотеку MPIR, что то с ней оно не заводится.

Так работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void main()
{
    //mpz_class i("0");
    //mpz_class k("1");
    //mpz_class l("1211728594799");
    int k = 9;
    int i = 0;
    int l = 1998899087;
 
#pragma omp parallel for
    for (i=k; i <= l; i++) {
        if (i == 1998899085)
            printf("kkk");
    }
 
    
    system("pause");
    
 
}
Так нет:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void main()
{
    mpz_class i("0");
    mpz_class k("1");
    mpz_class l("1211728594799");
    //int k = 9;
    //int i = 0;
    //int l = 1998899087;
 
#pragma omp parallel for
    for (i=k; i <= l; i++) {
        if (i == 1998899085)
            printf("kkk");
    }
 
    
    system("pause");
    
 
}
Получаем ошибки при сборке: C3015, C3017,C3019.
Если делаю //#pragma omp parallel for - всё нормально собирается. Т.е сам MPIR отрабатывает, но правда работает медленно. Что в этом случае не так?
0
mat_for_c
210 / 205 / 76
Регистрация: 26.04.2013
Сообщений: 957
Завершенные тесты: 3
31.10.2017, 15:18 #4
Цитата Сообщение от forks Посмотреть сообщение
Как же тогда останавливать цикл при использовании OpenMP
директиву omp for используют при распараллеливании циклов известной длины. если все же хотите тормозить цикл, то это будет выглядеть как-то так, приготовьтесь
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// примерно так должно выглядеть, могу ошибаться конечно
bool is_work(true);
int start = 0;
int N = 1998899085;
 
#pragma omp parallel
{
   uint i, stop;
 
   #pragma omp critical
   {
      i = start ;
      start += N / omp_get_num_threads();
      stop = start;
 
      if(omp_get_thread_num() == omp_get_num_threads()-1)
         stop = N;
   } 
 
   while(i < stop && is_work) {
      if(i == 1998899085) {
#pragma omp atomic 
            is_work= false;
         printf("kkk")     
      }
      i++;
   }
}


Цитата Сообщение от forks Посмотреть сообщение
хочу использовать библиотеку MPIR, что то с ней оно не заводится
не работал с MPI, ничем помочь не смогу
0
forks
0 / 0 / 0
Регистрация: 20.08.2016
Сообщений: 16
31.10.2017, 20:17  [ТС] #5
Да, код останова такой нехилый получается)).
Всё же не понимаю почему openmp не хочет работать с mpir, похоже что не расчитан он на это, а жаль...
0
31.10.2017, 20:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.10.2017, 20:17
Привет! Вот еще темы с решениями:

Openmp Распаралеливание цикла
//массив b, n,m,j является разделяемым между потоками и их значения сохраняется...

Сортировка с использованием OpenMP
Ребят, помогите пожалуйста распараллелить с помощью OpenMP сортировку подсчетом...

OpenMP при распараллеливании цикла иногда выдает разные результаты
Доброго времени суток, ув. форум! Я новичек и в С++ и в OpenMP Играюсь со...

Умножение матриц с использованием OpenMP
Здрасте. Есть следующая задача. Нужно реализировать умножение двух квадратных...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru