![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
BrookBond |
|
|||
![]() Возможно все..... Профиль Группа: Участник Сообщений: 17 Регистрация: 9.6.2012 Где: Санкт-Петербург Репутация: нет Всего: нет |
Приветствую знатоков!
Только начал изучать OpenMP и сразу попытался применить его на практике. Пишу прогу, которая в дальнейшем будет работать (сравнивать матрицы больших размеров) на многоядерном компе. Вот проблемная часть этой проги, где используется OpenMP и возникают непонятные мне действия. Код:
Проблема в том, что если внешний цикл по р запараллелить, то данные начинают смешиваться, выводятся хаотично так как показано на прикрепленном рисунке (самый правый столбец это значения внешнего цикла по р). А нужно чтобы они выводились последовательно, с начала то что считает первое ядро (0...3150), а затем второе (3151..6300), но чтоб считались параллельно. Подскажите пожалуйста, что добавить/убрать ? Прикреплен проект в Qt Creator, работаю на вин 7. Присоединённый файл ( Кол-во скачиваний: 5 ) ![]() |
|||
|
||||
BrookBond |
|
|||
![]() Возможно все..... Профиль Группа: Участник Сообщений: 17 Регистрация: 9.6.2012 Где: Санкт-Петербург Репутация: нет Всего: нет |
Вот скрин работы проги
Присоединённый файл ( Кол-во скачиваний: 12 ) ![]() |
|||
|
||||
Фантом |
|
|||
![]() Вы это прекратите! ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1516 Регистрация: 23.3.2008 Репутация: нет Всего: 49 |
Поскольку Вы используете параллельный цикл, то не можете (и не должны) предсказать, какая из итераций когда будет выполняться. Поэтому, если вывод нужен в строго определенном порядке, то надо сохранять где-то результаты счета, а уже потом в обычном последовательном цикле выполнять вывод результатов. Кстати, и с точки зрения итогового быстродействия это тоже разумнее. |
|||
|
||||
BrookBond |
|
|||
![]() Возможно все..... Профиль Группа: Участник Сообщений: 17 Регистрация: 9.6.2012 Где: Санкт-Петербург Репутация: нет Всего: нет |
Спасибо, сейчас как раз над этим работаю
|
|||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
По-моему надо просто написать:
Перед printf. А нет я не прав, надо еще один for запилить. Это сообщение отредактировал(а) Wuffur - 18.6.2013, 21:15 |
|||
|
||||
BrookBond |
|
|||
![]() Возможно все..... Профиль Группа: Участник Сообщений: 17 Регистрация: 9.6.2012 Где: Санкт-Петербург Репутация: нет Всего: нет |
Подскажите если знаете, вот такая проблема получается если использовать прагму. Первое ядро в цикле по р считает элементы от 0 до 3150, а второе 3151 - 6300. Но довольно часто получается, что второе ядро быстрее считает свою часть и в то время как первое ядро считает i-й элемент (внешний цикл) второе считает уже i+1 элемент и соответственно получается путаница в данных.
Как сделать так чтобы второе ядро ждало завершения счета первого ядра и потом уже они вместе переходили бы на i+1 элемент?
|
|||
|
||||
Wuffur |
|
||||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Как вариант сначала можно записать в массив, а потом в файл. То есть через указатели.
Ждать пока ядра завершаться:
я уже сказал. Мне тут нравится документация: IBM Linux OMP public documentation И у меня это код на linux`е segfault`ится. Вот ещё, вроде можно с :
Так даже в том коде работать должно. StackOverflow - is there an implicit barrier after omp critical section? MSDN Pragma OMP Critical Это сообщение отредактировал(а) Wuffur - 18.6.2013, 23:45 |
||||
|
|||||
BrookBond |
|
||||
![]() Возможно все..... Профиль Группа: Участник Сообщений: 17 Регистрация: 9.6.2012 Где: Санкт-Петербург Репутация: нет Всего: нет |
Подскажи пожалуйста код, а то никак не могу разобраться с барьером
При такой записи барьера результата нет, по прежнему идет перескок одного ядра на i+1 элемент, куда его поставить? |
||||
|
|||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Да , потому что потоки выполняются параллельно до барьера, синхронизируются и дальше выполняются параллельно, поэтому и перескакивает. Если выполняется дериктива #pragma omp critical, то компилятору говорится, что в этом участке кода нужно выполнять в один поток. Вся магия.
То есть если printf запихнуть в
то всё должно быть нормально. Что происходит когда ставишь барьерную синхронизацию на 3150 элементе? Наверное программа распараллеливает for между задачи между ядрами - один выполняет от 1 до 1575 другой от 1576 до 3150, а после от 3151 до 4725 и от 4726 до 6300. В таком случае на 6300-ом элементе её ставить нет смысла. Барьерная синхронизация нужна бы была, если бы у вас элементы в printf() передавались бы переменные из других значений итератора цикла for и у вас выводились еще неинициализированные на каких-то шагах итерации значения переменных. Но это совершенно не влияет на порядок их вывода на стандартный поток. Без барьерной синхронизации всё не так однозначно, порядок выполнение параллельных команд может зависеть от состояния кэша и каких-то физических факторов, к примеру температуры процессора. Вывод сначала в массив был лучше просто вывода в файл или стандартный поток тем, что можно было бы записать произвольно, а в файл(хотя конечно можно и произвольно с fseek, fwrite) и в стандартный поток записывается по порядку. Это сообщение отредактировал(а) Wuffur - 19.6.2013, 14:21 |
|||
|
||||
BrookBond |
|
||||||
![]() Возможно все..... Профиль Группа: Участник Сообщений: 17 Регистрация: 9.6.2012 Где: Санкт-Петербург Репутация: нет Всего: нет |
Получается что прога зависает (останавливается).
На это не похоже. попробовал сделать так
Становится гораздо лучше, данные выводит почти что верно, но я использую printf лишь для того чтоб отслеживать какие значения записываются в Obmen3 . А при такой записи все равно в Obmen3 записываются не по порядку, а нужно чтобы в этот массив записывались данные в том же порядке как и при работе на одном ядре. Help.... ![]() |
||||||
|
|||||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
А почему бы вам в массив не писать?
То есть я не совсем понимаю, что там инициализировалось:
Дебагер вам в руки. Это сообщение отредактировал(а) Wuffur - 19.6.2013, 15:17 |
|||
|
||||
BrookBond |
|
|||
![]() Возможно все..... Профиль Группа: Участник Сообщений: 17 Регистрация: 9.6.2012 Где: Санкт-Петербург Репутация: нет Всего: нет |
||||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Попробуйте раскомментить второй printf и проверить выполняются ли условия выражения if, если да, то проблема не внутри скобок.
Не знаю, может барьерная синхронизация перед критической секцией поможет, но мне кажется вряд ли. У меня ваша программа даже под 10-ой студией не запускается. Это сообщение отредактировал(а) Wuffur - 19.6.2013, 15:48 |
|||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Ну так printf пишет в стандартный поток, сделайте fprintf в критической секции будет писать в файл. |
|||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Попробуйте еще #pragma omp single вначале, чтобы одна нить исполняла одну секцию кода и #pragma omp barrier #pragma omp master перед файловым выводом.
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |