Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.57/14: Рейтинг темы: голосов - 14, средняя оценка - 4.57
9 / 8 / 3
Регистрация: 25.11.2017
Сообщений: 481
1

Распараллеливание

17.01.2020, 17:05. Просмотров 2736. Ответов 51
Метки нет (Все метки)

Подскажите, что не так. Есть массив из 13 элементов, мне нужно разбить на три блока, один блок может быть неполный. При этом чтоб была обработка размера последнего блока. И получит сумму каждого блока. Если запускаю без распараллеливания, то все считается правильно. Когда начинаю параллелить на уровне блока 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
#include <omp.h>
#include <iostream>
 
using namespace std;
 
void xor(const int* a, int size, int *res)
{
int temp = 0;
for(int j =0; j < size; j++) temp = temp + a[j];
*res=0;
}
int main()
{
int m1[13] = {78,90,34,78,123,43,89,111,17,10,67,80,123};
int result [3]={0};
int i =0, size =0, length =5;
omp_set_num_threads(omp_get_num_procs());
#pragma omp parallel for 
for(i =0; i < 3; i++)
{
if(i == 2) size = 3; else size = 5;
xor(m1+i*length, size, result+i);
}
return 0;
}
Добавлено через 44 секунды
Ну вот мне удалось с помощью остановки потока

Добавлено через 19 секунд
Но не знаю насколько это правильно или корректно

Добавлено через 3 минуты
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
#include <omp.h>
#include <iostream>
#include <mutex>
 
using namespace std;
std :: mutex g_lock;
void xor(const int* a, int size, int *res)
{
int temp = 0;
for(int j =0; j < size; j++) temp = temp + a[j];
*res=0;
}
int main()
{
int m1[13] = {78,90,34,78,123,43,89,111,17,10,67,80,123};
int result [3]={0};
int i =0, size =0, length =5;
omp_set_num_threads(omp_get_num_procs());
#pragma omp parallel for 
for(i =0; i < 3; i++)
{
g_lock.lock();
if(i == 2) size = 3; else size = 5;
xor(m1+i*length, size, result+i);
g_lock.unlock();
}
return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2020, 17:05
Ответы с готовыми решениями:

Распараллеливание
Всем добрый вечер. Если кто знает подскажите,мне надо распараллелить перемножение...

распараллеливание
Скажите, кто-нибудь занимался распараллеливанием в си++? В моих попытках что-либо распараллелить...

Распараллеливание циклов
Возникли трудности с освоением OpenMP Непонимаю, почему если закоментировать вот этот фрагмент...

Распараллеливание вычислений
Вычисляю произведение матриц несколькими потоками (количество задаётся пользователем). Потоки...

51
43 / 39 / 5
Регистрация: 16.09.2019
Сообщений: 285
17.01.2020, 17:35 2
Цитата Сообщение от Andy_Coldfield Посмотреть сообщение
*res=0;
Слыште, говорит, правильно у него все работает....
1
4550 / 3059 / 1281
Регистрация: 07.05.2019
Сообщений: 9,428
Записей в блоге: 1
17.01.2020, 18:24 3
Цитата Сообщение от Andy_Coldfield Посмотреть сообщение
Ну вот мне удалось с помощью остановки потока
Толко это последовательно получилось.
Попробуй сделать size локальным для потока
C++
1
2
3
4
5
6
7
8
9
10
#pragma omp parallel 
{
    int size;
    #pragma omp for 
    for (i = 0; i < 3; i++)
    {
        if (i == 2) size = 3; else size = 5;
        xor (m1 + i * length, size, result + i);
    }
}
Добавлено через 1 минуту
Либо
C++
1
2
3
4
5
6
#pragma omp parallel for private(size)
for(i =0; i < 3; i++)
{
if(i == 2) size = 3; else size = 5;
xor(m1+i*length, size, result+i);
}
1
9 / 8 / 3
Регистрация: 25.11.2017
Сообщений: 481
17.01.2020, 22:27  [ТС] 4
БедолагаЖека, банальная опечатка. Понятно, что *res=temp;


Добавлено через 7 минут
oleg-m1973, а есть ли возможность вывести как-нибудь информацию о запущенных потоках? Ведь потоки должны маркироваться или иметь ID?
0
4550 / 3059 / 1281
Регистрация: 07.05.2019
Сообщений: 9,428
Записей в блоге: 1
17.01.2020, 22:34 5
Цитата Сообщение от Andy_Coldfield Посмотреть сообщение
oleg-m1973, а есть ли возможность вывести как-нибудь информацию о запущенных потоках? Ведь потоки должны маркироваться или иметь ID?
C++
1
        std::cout << std::this_thread::get_id() <<< std::endl;
C++
1
        std::cout << ::GetCurrentThreadId() <<< std::endl;
0
9 / 8 / 3
Регистрация: 25.11.2017
Сообщений: 481
17.01.2020, 22:48  [ТС] 6
oleg-m1973, вы правы, все последовательно реализовывается... Да уже проверил потоки и все запускается в одном потоке...

Добавлено через 2 минуты
oleg-m1973, я в настройках проекта не включил многопоточность. У меня там openmp не включён был

Добавлено через 15 секунд
oleg-m1973, я в настройках проекта не включил многопоточность. У меня там openmp не включён был
0
4550 / 3059 / 1281
Регистрация: 07.05.2019
Сообщений: 9,428
Записей в блоге: 1
17.01.2020, 22:52 7
Цитата Сообщение от Andy_Coldfield Посмотреть сообщение
oleg-m1973, я в настройках проекта не включил многопоточность. У меня там openmp не включён был
И при этом первый вариант не работал?

Добавлено через 1 минуту
Параллельная программа на OpenMP выполняется очень медленно

Добавлено через 10 секунд
Параллельная программа на OpenMP выполняется очень медленно
0
9 / 8 / 3
Регистрация: 25.11.2017
Сообщений: 481
17.01.2020, 23:03  [ТС] 8
oleg-m1973, я немного видоизменили private добавил ещё индекс i.
0
4550 / 3059 / 1281
Регистрация: 07.05.2019
Сообщений: 9,428
Записей в блоге: 1
17.01.2020, 23:05 9
Цитата Сообщение от Andy_Coldfield Посмотреть сообщение
oleg-m1973, я немного видоизменили private добавил ещё индекс i.
Убери, там openmp сам разберётся
0
9 / 8 / 3
Регистрация: 25.11.2017
Сообщений: 481
18.01.2020, 05:37  [ТС] 10
oleg-m1973, это он настолько самостоятельный?
0
579 / 436 / 170
Регистрация: 23.04.2019
Сообщений: 1,871
18.01.2020, 13:15 11
Цитата Сообщение от Andy_Coldfield Посмотреть сообщение
это он настолько самостоятельный
oleg-m1973, фигни не посоветует)
0
4550 / 3059 / 1281
Регистрация: 07.05.2019
Сообщений: 9,428
Записей в блоге: 1
18.01.2020, 15:37 12
Цитата Сообщение от Andy_Coldfield Посмотреть сообщение
oleg-m1973, это он настолько самостоятельный?
Ну а как ты сам думаешь, что просто написав слово #pragma ты всё круто распареллелил?
Попробуй написать это распараллеливание сам, без openmp, быстро поймёшь, насколько он самостоятельный.
1
9 / 8 / 3
Регистрация: 25.11.2017
Сообщений: 481
24.01.2020, 22:51  [ТС] 13
oleg-m1973, а не подскажите как реализовать разбиение на блоки, чтоб потом результаты склеивались в один блок и в итоге получилось одно число....

есть массив [57, 907, 65, 1 , 6 , 90, 76, 89, 90, 43, 51, 1234, 6431, 809, 9076, 890]. Его разбивать на блоки длины 3. в блоке находить максимум, дальше максимальные числа склеивать.
57, 907, 65 - 907
1,6,90 - 90
76,89,90 - 90
и так далее...
907,90,90 - 907
Как это лучше реализовать?
0
4550 / 3059 / 1281
Регистрация: 07.05.2019
Сообщений: 9,428
Записей в блоге: 1
25.01.2020, 16:08 14
Лучший ответ Сообщение было отмечено Andy_Coldfield как решение

Решение

Цитата Сообщение от Andy_Coldfield Посмотреть сообщение
Как это лучше реализовать?
На openmp, к сожалению, не знаю.
На обычных потоках что-то типа (не проверял)
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
static int data[] = {57, 907, 65, 1 , 6 , 90, 76, 89, 90, 43, 51, 1234, 6431, 809, 9076, 890};
 
 
static const size_t block_size = 3;
static const size_t sz = std::size(data);
static std::atomic<size_t> idx{0};
static std::atomic<int> max_val{data[0]};
 
void ThreadProc()
{
    for(;;)
    {
        size_t i = idx.fetch_add(block_size);
        if (i > sz)
            break;
 
        int mx = data[i++];
        for (const size_t end = std::min(i + block_size - 1, sz); i < end; ++i)
            if (mx < data[i])
                mx = data[i];
 
        printf("local max: %u", mx);
 
        int mx2 = max_val;
        while (mx2 < mx)
            max_val.compare_exchange_strong(mx2, mx);
    }
}
1
9 / 8 / 3
Регистрация: 25.11.2017
Сообщений: 481
25.01.2020, 20:26  [ТС] 15
oleg-m1973, просто трудно даются потоки) А точнее поточное программирование и распараллеливание))) Но от души спасибо))
0
0 / 0 / 0
Регистрация: 02.06.2015
Сообщений: 7
15.03.2020, 16:20 16
Добрый день. Использовал OpenMP в VC2010. Попытался перейти на VC2019. При отладке консольного приложения с включенной опцией "Поддержка Open MP" появляется ошибка такого вида:
Ошибка C2338 двухэтапный поиск имен не поддерживается для C++/CLI, C++/CX или OpenMP. Используйте /Zc:twoPhase- Proba_OMP_3
Подскажите, пожалуйста, в чем можеть быть причина этого. Спасибо.
0
4550 / 3059 / 1281
Регистрация: 07.05.2019
Сообщений: 9,428
Записей в блоге: 1
15.03.2020, 16:32 17
Цитата Сообщение от abakankmf Посмотреть сообщение
Ошибка C2338 двухэтапный поиск имен не поддерживается для C++/CLI, C++/CX или OpenMP. Используйте /Zc:twoPhase- Proba_OMP_3
Подскажите, пожалуйста, в чем можеть быть причина этого. Спасибо.
/Zc:twoPhase пробовал использовать?
А скорее всего - проект криво создал (или был кривой до этого)
0
9 / 8 / 3
Регистрация: 25.11.2017
Сообщений: 481
15.03.2020, 16:43  [ТС] 18
abakankmf, попробуй полностью пустой проект создать. И потом уже в настройках проекта выбери язык с++, и либу с OMP подключай. И все должно работать:-)
0
0 / 0 / 0
Регистрация: 02.06.2015
Сообщений: 7
15.03.2020, 17:49 19
Пробовал по-разному: и пустой создал, и на основе шаблона консольного приложения. Совершенно пустой проект,
даже не обращаюсь к функциям OpenMP, все равно появляется эта ошибка. А как использовать /Zc:twoPhase пробовал использовать?
0
4550 / 3059 / 1281
Регистрация: 07.05.2019
Сообщений: 9,428
Записей в блоге: 1
15.03.2020, 17:54 20
Цитата Сообщение от abakankmf Посмотреть сообщение
Пробовал по-разному: и пустой создал, и на основе шаблона консольного приложения. Совершенно пустой проект,
даже не обращаюсь к функциям OpenMP, все равно появляется эта ошибка. А как использовать /Zc:twoPhase пробовал использовать?
Покажи код
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.03.2020, 17:54

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

Распараллеливание программы
Помогите эту последовательную программу распараллелить на параллельных 2 процесса. #include...

Распараллеливание вычислений
Здравствуйте. Может кто сможет подсказать как мне решить следующую задачу: необходимо...

Странное распараллеливание
Добрый вечер, коллеги. У меня следующая проблема. Преподаватель сказал распараллелить программу,...

Распараллеливание циклов
Доброго времени суток. Возникла необходимость распараллелить один численный алгоритм средствами...

Распараллеливание цикла
есть цикл for (unsigned n = 0; n &lt; threads; n++) { func (sigma, sub_noisy, sub_basic,...

Распараллеливание циклов
Есть такой цикл std::list&lt;int&gt;::iterator iter; std::list&lt;int&gt;_paramsFFT; for(iter =...


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

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

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