Название: Помогите с распараллеливанием потоков. Отправлено: Alexu007 от Сентябрь 09, 2014, 07:47 Вещь для меня новая, прошу помощи более опытных.
Есть вложенный цикл, например решето Эрастофена: Код
Ну где-то так. На моём компе работает 6 минут, хотелось бы ускорить, и заодно потоки выучить. Поэтому идея: допустим имеем 2 потока, каждый из которых может вычислять внутренний цикл. Внешний цикл проверяет, свободен ли поток, и если свободен - запускает его на выполнение. При этом ставится флаг занятости потока. После окончания вычислений поток сбрасывает флаг занятости. И так далее. Вопросы: реализуемо ли это в принципе, и будет ли выигрышь во времени, т.е. будут ли при этом работать 2 ядра процессора? Название: Re: Помогите с распараллеливанием потоков. Отправлено: gil9red от Сентябрь 09, 2014, 07:57 Посмотрите в сторону OpenMP (http://ru.wikipedia.org/wiki/OpenMP):)
Название: Re: Помогите с распараллеливанием потоков. Отправлено: m_ax от Сентябрь 09, 2014, 10:44 Цитировать Ну где-то так. На моём компе работает 6 минут, хотелось бы ускорить, и заодно потоки выучить. У вас алгоритм не оптимально реализован.И от распараллеливания здесь врят ли будет существенный выйгрыш.. Название: Re: Помогите с распараллеливанием потоков. Отправлено: vizir.vs от Сентябрь 09, 2014, 11:58 Решето Эратосфена не самый лучшей способ поиска простых чисел. Этот метод можно ускорить
Название: Re: Помогите с распараллеливанием потоков. Отправлено: Igors от Сентябрь 09, 2014, 12:16 [off]
выигрышь/выйгрыш - вспоминается классика Цитировать ...на котором красовалась надпись: ВАСТОК-2. Я подошел и исправил обе ошибки: ВОСТОГ-2 [/off] :)Что касается распараллеливания - то надо сначала для него переделать алгоритм (так бывает часто). Здесь хорошо на atomic. Главная нитка ищет след простое число, а в это время др нитки занимаются "вычеркиванием". Надо только не пускать главную дальше "уже вычеркнутого" Внешний цикл проверяет, свободен ли поток, и если свободен ... На эти грабли наступают абсолютно все - и много раз :)Название: Re: Помогите с распараллеливанием потоков. Отправлено: Alexu007 от Сентябрь 09, 2014, 20:48 Цитировать Ну где-то так. На моём компе работает 6 минут, хотелось бы ускорить, и заодно потоки выучить. У вас алгоритм не оптимально реализован.И от распараллеливания здесь врят ли будет существенный выйгрыш.. Ну так, к слову, эрастофена я оптимизировал. Во первых, внешний цикл достаточно тянуть до кв. корня. Во вторых, я выкинул чётные числа - в 2 раза расход памяти уменьшился и в 2 раза шустрей работать стал: Код
Название: Re: Помогите с распараллеливанием потоков. Отправлено: m_ax от Сентябрь 09, 2014, 22:42 Цитировать Дело не в алгоритме. Я не пишу никакую программу и эти простые числа мне не нужны. Просто, когда я запускаю эту прогу, комп показывает загрузку 25% - это одно ядро процессора. Интересно было бы попробовать загрузить 2 ядра или 4. Так я о том и говорю.. Вы выбрали пример, где распараллеливание не даст заметного выйгрыша, поскольку операция итерирования примерно совпадает по порядку с операцией во внутреннем цикле:Код + Надо ещё учитывать затраты на создание потоков и т.п.. Короче, ваша задача едва ли раскроет тот потенциал, который можно извлечь от распараллеливания.. Я бы не стал именно здесь на этом замарачиваться, имхо.. Но, как уже здесь упоминалось, вы можете это легко проверить с помощью OpenMP) Но есть, например, другие задачи, когда это существенно может ускорить время вычислений. Сам сейчас этим занимаюсь (особенно после того, как прикупил себе AMD FX 8350)) В частности, мне часто приходиться использовать распараллеленную версию std алгоритма transform. О реализации можно почитать, например здесь: http://www.prog.org.ru/topic_25963_15.html (http://www.prog.org.ru/topic_25963_15.html) :) Название: Re: Помогите с распараллеливанием потоков. Отправлено: Igors от Сентябрь 10, 2014, 08:42 Вы выбрали пример, где распараллеливание не даст заметного выйгрыша, поскольку операция итерирования примерно совпадает по порядку с операцией во внутреннем цикле: Основное время уходит на "вычеркивание" и эти операции независимы - поэтому даст. Другое дело что задача достаточно трудная. Да еще и учебная - поэтому заморачиваться и не хочется.Код Вот здесь надо каким-то образом проверить было ли значение в буфере уже "пройдено" всеми остальными нитками или еще нет. По ходу дела for(uint i = 0; i < sqrt(N)+1; i++) Вероятно компилятор это оптимизирует, но все равно грамотно будет вычислить счетчик самому до циклаНазвание: Re: Помогите с распараллеливанием потоков. Отправлено: Igors от Сентябрь 10, 2014, 11:25 Да, есть прозаичный, хотя и громоздкий, способ:
- находим все простые числа напр в диапазоне от 0 до 100 - запускаем "вычеркивание" всеми нитками для полного диапазона - находим простые в след диапазоне - напр от 100 до 1000 и.т.д Можно и по-другому, с LRU или даже с std::set ... Название: Re: Помогите с распараллеливанием потоков. Отправлено: Bepec от Сентябрь 10, 2014, 11:33 А разве openmp не забирает на себя полностью эти проблемы? Насколько мне объясняли, openmp просто бьёт цикл на N частей и каждый отдаёт потоку. Собственно этим и достигается распараллеливание.
Название: Re: Помогите с распараллеливанием потоков. Отправлено: Igors от Сентябрь 10, 2014, 13:38 А разве openmp не забирает на себя полностью эти проблемы? Насколько мне объясняли, openmp просто бьёт цикл на N частей и каждый отдаёт потоку. Собственно этим и достигается распараллеливание. Он может бить всяко-разно и диспатчить, напрКод Но он не отвечает за зависимость одного вычисления (тела цикла) от другого, а здесь она есть. Откройте в вике "решето Эрастофена" Название: Re: Помогите с распараллеливанием потоков. Отправлено: Alexu007 от Сентябрь 10, 2014, 14:00 Цитировать Вероятно компилятор это оптимизирует, но все равно грамотно будет вычислить счетчик самому до цикла Я проверял, по времени работает одинаково. Но если так неграмотно - поменяю. |