Название: Помогите распараллелить цикл Отправлено: nata267 от Апрель 11, 2014, 14:58 Друзья, не могу найти инфу как распараллелить цикл. Любой цикл не важно. Например, такой:
Код: for (int it = 0; it < numIterations; it++) { Только начинаю изучать многопоточность. Инструмент не важен. Главное чтобы это было не автоматическое распараллеливание как в OpenMP. Мне важен сам принцип распараллеливания. Как и где создавать потоки, мьютексы и т д как они обмпениваются значениями и переменными и.т.д. Название: Re: Помогите распараллелить цикл Отправлено: Vamireh от Апрель 11, 2014, 15:35 Разбиваете numIterations на N отрезков
Да хоть наследуетесь от QThread, в конструктор передаете индексы начала и конца отрезка, а также указатель на общие данные В перегруженном run() выполянете нужный вам код для этого отрезка Создаете N экземпляров этого класса Для каждого вызываете start() Для каждого вызываете wait() Если данные только читать, то можно как-то так. Если в данные надо что-то писать, то вдовесок в конструктор передаете указатель на мьютекс, а в методе run() перед записью его блокируйте, а после записи - разблокируйте. Если очень грубо, то так. Название: Re: Помогите распараллелить цикл Отправлено: Vamireh от Апрель 11, 2014, 15:44 Ну или создаете просто класс, который делает этот цикл, а в параметре метода - начальный и конечный индекс. В начале метода блокируете мьютекс, в конце - разблокруйте.
Наследуетесь от того же QThread, передаете указатель на экземпляр первого класса. И в run вызваете его для нужного интервала. Опять создаете сколько нужно потоков, для всех start() и wait(). Я бы скорее по такой схеме делал. Название: Re: Помогите распараллелить цикл Отправлено: nata267 от Апрель 11, 2014, 15:59 Ну или создаете просто класс, который делает этот цикл, а в параметре метода - начальный и конечный индекс. В начале метода блокируете мьютекс, в конце - разблокруйте. Наследуетесь от того же QThread, передаете указатель на экземпляр первого класса. И в run вызваете его для нужного интервала. Опять создаете сколько нужно потоков, для всех start() и wait(). Я бы скорее по такой схеме делал. Большое спасибо, попробую так Название: Re: Помогите распараллелить цикл Отправлено: OKTA от Апрель 11, 2014, 17:32 Чтобы не мучиться с QThread, посмотрите в сторону QtConcurrentRun и вообще в http://qt-project.org/doc/qt-4.8/threads-qtconcurrent.html
Название: Re: Помогите распараллелить цикл Отправлено: Vamireh от Апрель 11, 2014, 17:46 Чтобы не мучиться с QThread, посмотрите в сторону QtConcurrentRun и вообще в http://qt-project.org/doc/qt-4.8/threads-qtconcurrent.html Да, это гораздо проще, но: Цитировать Главное чтобы это было не автоматическое распараллеливание как в OpenMP. Мне важен сам принцип распараллеливания. Как и где создавать потоки, мьютексы и т д как они обмпениваются значениями и переменными и.т.д. Название: Re: Помогите распараллелить цикл Отправлено: nata267 от Апрель 12, 2014, 22:14 Может быть распараллеливать цикл - плохая идея? Может быть не любой цикл возможно распараллелить?
Название: Re: Помогите распараллелить цикл Отправлено: Vamireh от Апрель 15, 2014, 05:50 Если каждая следующая итерация не зависит от предыдущих, то можно распараллелить. Однако не всегда это панацея, я лично встречал случаи когда два цикла последовательно работали быстрее, чем их запараллелить или их тела в один цикл вынести.
Также, например, я параллельными циклами ускорил одну программу раза в 4(на своей машине), но когда стали запускать на машинах клиента (не очень современное железо), то оказалось, что параллельная версия работает раз в 6 медленнее непараллельной, при этом всю систему вешает. В общем, если все устраивает - не надо ничего не делать. (только ради интереса, самообразования и т.д.) Название: Re: Помогите распараллелить цикл Отправлено: Igors от Апрель 15, 2014, 10:15 ...Любой цикл не важно. В действительности все это важно. "Любой цикл" - совершенно неверный подход. "Кластер" должен быть приличным чтобы распараллеливание имело смысл. Если делать самому то выглядит примерно так...Инструмент не важен. ...Мне важен сам принцип распараллеливания. - завести N ниток для параллельной работы, которые пока спят - разбить задачи цикла на кучки, в простейшем случае дать каждой рабочей нитке примерно одинаковое число задач - запустить каждую рабочую нитку дав ей "свои" задачи - дождаться окончания работы каждой рабочей и усыпить ее Реализовать это непросто, напр прямолинейное усыпление/пробуждение ниток может оказаться неприемлемо медленным. Поэтому надо подбирать инструмент. Я пользуюсь OpenMP и очень доволен. Qt аналог - QtConcurrent. По поводу мутексов, обмена данными и.т.п. - это "синхронизация", отношение к распараллеливанию имеет косвенное. Название: Re: Помогите распараллелить цикл Отправлено: OKTA от Апрель 15, 2014, 12:12 И добавлю к вышесказанному, что даже использование "автоматических" средств, как QtConcurrent и OpenMP не избавляет от необходимости использования средств синхронизации потоков, самостоятельной организации обмена данными между потоками и т.д. и т.д....
|