Конструкции Fortran 95, такие как WHERE, FORALL и SPREAD, обычно приводят к ускорению параллельного кода?
Я прочитал книгу Fortran 95 от Metcalf, Reid and Cohen и Numerical Recipes в Fortran 90. Они рекомендуют использовать WHERE, FORALL и SPREAD среди прочего, чтобы избежать ненужной сериализации вашей программы.
Тем не менее, я наткнулся на этот ответ, в котором утверждается, что FORALL хорош в теории, но на практике бессмысленна - вы также можете писать циклы, поскольку они точно так же параллельны и вы можете явно их раскрыть с помощью OpenMP (или автоматических функций некоторых компиляторов, таких как Intel).
Может ли кто-нибудь проверить из опыта, нашли ли они, как эти конструкции, какие-либо преимущества перед явными циклами, и если утверждения в терминах параллельной производительности?
И есть ли какие-либо другие параллельные особенности языка, которые хороши в принципе, но не стоят на практике?
Я понимаю, что ответы на эти вопросы несколько зависят от реализации, поэтому меня больше всего интересуют gfortran, процессоры Intel и SMP parallelism.
Ответы
Ответ 1
Как я уже сказал в своем ответе на другой вопрос, существует общее мнение, что FORALL не так полезен, как надеялся, когда он был введен в язык. Как уже объяснялось в других ответах, он имеет ограничительные требования и ограниченную роль, а компиляторы стали довольно хорошими в оптимизации регулярных циклов. Компиляторы продолжают улучшаться, а возможности варьируются от компилятора к компилятору. Другая подсказка заключается в том, что Fortran 2008 снова пытается... помимо добавления явной распараллеливания к языку (со-массивы, уже упомянутые), есть также "делать параллельные", новую форму цикла, которая требует ограничений, которые должны лучше разрешать компилятор для выполнения автоматических оптимизаций парализации, но должны быть достаточно общими, чтобы быть полезными - см. ftp://ftp.nag.co.uk/sc22wg5/N1701-N1750/N1729.pdf.
С точки зрения получения скорости, в основном я выбираю хорошие алгоритмы и программу для удобочитаемости и ремонтопригодности. Только если программа слишком медленная, я обнаруживаю узлы бутылки и перекодирую или реализую многопоточность (OpenMP). Это будет редкий случай, когда FORALL или WHERE против явного цикла do будут иметь значимую разницу в скорости - я бы больше посмотрел, насколько четко они заявляют о намерении программы.
Ответ 2
Я внимательно посмотрел на это и, грустно сообщить, обычно обнаружил, что писать мои циклы явно приводит к более быстрым программам, чем к параллельным конструкциям, о которых вы пишете. Даже простые назначения целых массивов, такие как A = 0
, как правило, превосходят do-loops.
У меня нет данных, и если бы я это сделал, это было бы устаревшим. Я действительно должен все это вставить в тестовый пакет и попробовать снова, компиляторы действительно улучшатся (иногда они становятся хуже).
Я все еще использую параллельные конструкции, особенно операции с целым массивом, когда они являются наиболее естественным способом выразить то, что я пытаюсь достичь. Я никогда не тестировал эти конструкции внутри конструкций OpenHM. Я действительно должен.
Ответ 3
FORALL - это обобщенная операция присваивания маскировки (как есть WHERE). Это не циклическая конструкция.
Компиляторы могут параллелизировать FORALL/WHERE с помощью SIMD-инструкций (SSE2, SSE3 и т.д.) и очень полезно получить немного низкоуровневой параллелизации. Конечно, некоторые более плохие компиляторы не беспокоят и просто сериализуют код как цикл.
OpenMP и MPI более полезны на более грубом уровне детализации.
Ответ 4
Теоретически использование таких назначений позволяет компилятору знать, что вы хотите сделать, и должно позволить ему оптимизировать его лучше. На практике см. Ответ от Марка... Я также считаю это полезным, если код выглядит более чистым. Я сам использовал такие вещи, как FORALL
, но не заметил никаких изменений производительности по сравнению с регулярными циклами DO
.
Что касается оптимизации, какой тип параллелизма вы намерены использовать? Мне очень не нравится OpenMP, но я предполагаю, что если вы намерены использовать это, вы должны сначала проверить эти конструкции.
Ответ 5
* Это должен быть комментарий, а не ответ, но он не будет вписываться в эту маленькую коробку, поэтому я помещаю ее здесь. Не держите его против меня:-) В любом случае, чтобы немного продолжить комментарий @steabert к его ответу. OpenMP и MPI - две разные вещи; один из них редко выбирает между ними, поскольку он более продиктован вашей архитектурой, чем личный выбор. Что касается изучения концепций параллеллизма, я бы рекомендовал OpenMP в любой день; это проще, и в дальнейшем легче перейти на MPI.
Но это не то, что я хотел сказать. Это - несколько дней назад, Intel объявила, что она начала поддерживать Co-Arrays, функцию F2008, ранее поддерживаемую только g95. Они не собираются ставить g95, но факт остается фактом: компилятор Intel более широко используется для производственного кода, поэтому это определенно интересная линия разработки. Они также изменили некоторые вещи в своем компиляторе Visual Fortran (имя для начала: -)
Дополнительная информация после ссылки: http://software.intel.com/en-us/articles/intel-compilers/