Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.85/48: Рейтинг темы: голосов - 48, средняя оценка - 4.85
6 / 6 / 0
Регистрация: 27.11.2016
Сообщений: 80

Многопоточное программирование: как распараллелить цикл?

12.05.2019, 19:06. Показов 10394. Ответов 45

Студворк — интернет-сервис помощи студентам
Здравствуйте, господа. Возможно, я сейчас спрошу глупость, но тем не менее. В интернетах найти ответа не смог.

Допустим, у меня есть цикл do-while, в котором у меня выполняются операции - функции - с большуууууущим вектором,
таких функций несколько, причем эти функции принципиально последовательны, результат работы предыдущей функции
влияет на выполнение последующей. Но в пределах одной функции, которая работает с вектором поэлементно вполне
возможно реализовать параллельные вычисления для ускорения процесса. Вопрос! А как это сделать правильно?
В каждой функции есть range-based цикл, который перебирает элементы вектора.

Мне пришел в голову (тупой) вариант - просто распилить вектор, допустим, на 4 части и работать с каждой из частей,
получилось примерно следующее:

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
29
30
31
32
33
34
35
36
37
38
39
#include <vector>
#include "MyClass"
#include "f1"
#include "f2"
 
int main()
{
 
std::vector<MyClass> V_1;
std::vector<MyClass> V_2;
std::vector<MyClass> V_3;
std::vector<MyClass> V_4;
 
do
{
/********************************/
/* какая-то инициализация векторов */
/********************************/
 
//Работа с векторами 1 (функция f1 принимает вектор по ссылке 
//и работает с его элементами range-based циклом)
 
f1(V_1);
f1(V_2);
f1(V_3);
f1(V_4);
 
//Работа с векторами 2 (функция f2 принимает вектор по ссылке 
//и работает с его элементами range-based циклом)
 
f2(V_1);
f2(V_2);
f2(V_3);
f2(V_4);
 
}while (/*условие*/)
 
return 0;
}
Как я уже отмечал, параллельно выполнять операции f1 и f2 я не могу, так как f2 использует результат работы f1.
Но я могу засунуть выполнение, допустим, f1(V_1..4) в разные потоки и выполнять это дело параллельно.

Мой очень фиговый вариант:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <vector>
#include <thread>
#include "MyClass"
#include "f1"
#include "f2"
 
int main()
{
 
std::vector<MyClass> V_1;
std::vector<MyClass> V_2;
std::vector<MyClass> V_3;
std::vector<MyClass> V_4;
 
do
{
/********************************/
/* какая-то  инициализация векторов */
/********************************/
 
//Работа с векторами 1 (функция f1 принимает вектор по ссылке 
//и работает с его элементами range-based циклом)
 
std::thread t1([&]() { f1(V_1); });
std::thread t2([&]() { f1(V_2); });
std::thread t3([&]() { f1(V_3); });
f1(V_4);
 
t1.join();
t2.join();
t3.join();
 
//Работа с векторами 2 (функция f2 принимает вектор по ссылке 
//и работает с его элементами range-based циклом)
 
std::thread t4([&]() { f2(V_1); });
std::thread t5([&]() { f2(V_2); });
std::thread t6([&]() { f2(V_3); });
f2(V_4);
 
t4.join();
t5.join();
t6.join();
 
}while (/*условие*/)
 
return 0;
}
В принципе, такая краказябра даже работает. Но ее огромный недостаток - я в цикле постоянно открываю-закрываю кучу
потоков, и в результате вместо выигрыша в скорости от параллельных вычислений я получаю проигрыш в этой самой скорости
по сравнению даже со случаем тупого последовательного счета.

Я бы хотел (хотел бы я, ага...), чтобы у меня где-то в мэйне открывалось три потока, в которые я бы по мере необходимости
закидывал выполнение нужных функций. Но с библиотекой thread такого добиться не получается. Находил в интернетах
информацию, что можно использовать библиотеку pthread.h, но я так понял, что она типа устаревшая, я ее в моей VS-2017
даже подключить не могу.

Как быть?

Заранее благодарю за уделенное внимание)
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.05.2019, 19:06
Ответы с готовыми решениями:

Как распараллелить цикл while?
Доброго времени суток. При распараллелировании применять технологии Openmp. Было бы здорово, если бы ответ на вопрос, что в заглавии,...

Распараллелить цикл
Распараллелить цикл: For(i=2;i&lt;N;i++) For(j=2;i&lt;N;j++) A =A +A; #include &lt;iostream&gt; #include &lt;omp.h&gt; #include...

Многопоточное программирование
Добрый вечер, есть программа, которая ищет окно HWND Handle_ArcheAge; Handle_ArcheAge = FindWindow(L&quot;ArcheAge&quot;, NULL); //ищем...

45
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
23.05.2019, 15:36
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Юрий Мамонтов Посмотреть сообщение
Покажи, хотя бы, как ты их пишешь
Сейчас сделаю их так, как я их вижу в "атомарном виде"
Подозреваю, там изменяются одновремременно несколько переменных, например a, b и с
0
6 / 6 / 0
Регистрация: 27.11.2016
Сообщений: 80
23.05.2019, 15:55  [ТС]
Подозреваю, там изменяются одновремременно несколько переменных, например a, b и с
Не а б и с, но вы правы, сразу несколько переменных, но все это под блокировкой, как я показал выше

А это проблема, что изменяются несколько переменных? Они ещё и к разным ячейкам mesh могут относиться
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
23.05.2019, 16:03
Цитата Сообщение от Юрий Мамонтов Посмотреть сообщение
Не а б и с, но вы правы, сразу несколько переменных, но все это под блокировкой, как я показал выше
Где?

Добавлено через 37 секунд
Цитата Сообщение от Юрий Мамонтов Посмотреть сообщение
А это проблема, что изменяются несколько переменных? Они ещё и к разным ячейкам mesh могут относиться
Если они взаимосвязаны, то должны изменяться синхронно

Добавлено через 3 минуты
В общем, скорее всего в классе Spher_1D_Area тебе понадобится мьютекс
0
6 / 6 / 0
Регистрация: 27.11.2016
Сообщений: 80
23.05.2019, 16:08  [ТС]

Где?
C++
1
2
3
4
5
6
7
8
9
10
11
12
for (auto &i : V_1..procs)
   {
       /***ОПРЕДЕЛЕНИЕ ОБРАЩЕНИЯ К КОНКРЕТНОЙ ЯЧЕЙКЕ МАССИВА mesh***/
       p = /* Number */;//Вычислили номер ячейки сетки
      //Какие-то действия
       {
    std::lock_guard<std::mutex> Lock_f(m_f);
    ++mesh[p].Value;
        ++Contr_Sum;
        ++Count;
       }
   }
Вот здесь под Лок Гардом изменяются поля Ro, Quantity - в Ro прибавляется то, что было насчитано выше в цикле

Добавлено через 2 минуты

В общем, скорее всего в классе Spher_1D_Area тебе понадобится мьютекс
oleg-m1973, у меня объявлен мьютекс прямо в функции
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
23.05.2019, 16:24
Цитата Сообщение от Юрий Мамонтов Посмотреть сообщение
Вот здесь под Лок Гардом изменяются поля Ro, Quantity - в Ro прибавляется то, что было насчитано выше в цикле
Вообще, в таких задачах лучше, чтобы потоки вообще не записывали никаких общих данных. Т.е. не использовали никакие блокировки.
Пусть выполняют свои расчёты, сохраняют у себя промежуточные результаты, а когда закончат - пробегаешься по этим результатам (их очень мало ~кол-во процессоров) и делаешь окончательные расчёты - суммируешь и всё такое, тоже без блокировок.
0
6 / 6 / 0
Регистрация: 27.11.2016
Сообщений: 80
24.05.2019, 08:50  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Думаю, лучше не надо std::atomic это нифига не бесплатная штука.
Да уж, не бесплатная... Переделал только ОДНУ переменную в атомик - скорость упала раз в 10... Зато, надо сказать, оно работает!
То есть проблема с несовпадением контрольной суммы и длинами векторов решилась, теперь все работает четко. Но мееееееедленно....
Даже в однопоточном режиме быстрее..

Добавлено через 3 минуты
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Вообще, в таких задачах лучше, чтобы потоки вообще не записывали никаких общих данных. Т.е. не использовали никакие блокировки.
Пусть выполняют свои расчёты, сохраняют у себя промежуточные результаты, а когда закончат - пробегаешься по этим результатам (их очень мало ~кол-во процессоров) и делаешь окончательные расчёты - суммируешь и всё такое, тоже без блокировок.
Придется делать так, потому что другого выхода я не вижу: атомарные операции слишком затратны, а простые блокировки почему-то не вывозят.

В любом случае, oleg-m1973, спасибо огромное за помощь, за время обсуждения моего проекта я реально
многому научился) буду продолжать работать

Добавлено через 3 минуты
Termit779, спасибо за книгу, очень пригодилась при разбирательствах)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.05.2019, 08:50

многопоточное программирование на с++
необходимо создать приложение которое с использованием thread (потоков) решит уравнение ну например дроюбное , то есть один поток решит...

Многопоточное программирование
Добрый день! Можете посоветовать кнгиги по многопоточному программированию на C++, не привязанные к ОС, использую Qt. Желательно, что...

Многопоточное программирование
Как я понимаю, есть много библиотек, с помощью которых мы можем использовать многопоточность. Чем они отличаются? Какая лучше? Почему? ...

Многопоточное программирование
Доброго времени суток! Пытался разобраться но не нашел понятных ответов на некоторые вопросы, поэтому, пожалуйста, не отсылайте к...

Не получается распараллелить цикл
Добрый день! В ходе опытов я выяснил, что распараллеливание цикла for с помощью OMP не приносит выигрыша во времени. Т.е. код...


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

Или воспользуйтесь поиском по форуму:
46
Ответ Создать тему
Новые блоги и статьи
Сукцессия 20. Война автоботов. Делаем ставки. Лёд против "пш-пш!".
anaschu 11.07.2026
Битва ИИ в ризосфере: Как мы скрестили жесткие ОДУ, закон Фика и «подземный шантаж» Уважаемые коллеги! Хочу поделиться уникальным опытом ведения междисциплинарной компьютерной разработки. Прямо. . .
Сукцессия 19. Какие выводы я сделал из модели? Часть 2.Внутримикоризный стехиометрический буфер и хроно-дискретные зоны экспансии
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования
Сукцессия 18. Какие выводы я сделал из войны грибов с деревьями? Часть 1- рассказ и немного про термины
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования Система ОДУ описывает динамику изменения массы различных компонентов системы во времени. Ключевой. . .
Просветление в 5 секунд
kumehtar 10.07.2026
Андрей Веретенников выдал фразу недавно: "Вам не обязательно кем-то себя считать"
Эксперимент с картинкой-обложкой на CodinGame
Adler 10.07.2026
Решил на днях провести эксперимент. У меня есть аккаунт на CodinGame, ТОП-3 по РФ среди 2200 участников (в разделе соревнования по программированию ИИ-ботов). Там есть обложка, куда можно влепить. . .
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru