Почему мой параллельный решатель медленнее моего последовательного решателя?

14

Я играл с PETSc и заметил, что когда я запускаю свою программу с несколькими процессами через MPI, она, кажется, работает еще медленнее ! Как я могу проверить, что происходит?

Шон Фарли
источник
Не публиковать это как ответ, потому что это действительно «что», а не «как», но в прошлом у меня были подобные проблемы, которые были вызваны тем, что часть кода, защищенная мьютексом, открывалась из нескольких потоков. Иногда вам нужно проверить блокировку общих ресурсов за кулисами.
Дэвид Z

Ответы:

13

Это может возникнуть из-за архитектурных факторов:

Если для одного или нескольких процессов доступна одинаковая пропускная способность памяти, то вы почти не увидите ускорения, поскольку SpMV и связанные операции линейной алгебры ограничены пропускной способностью памяти.

Может также случиться так, что накладные расходы на коммуникацию перевешивают ваши локальные вычисления. Например, в линейных итерационных методах мы рекомендуем иметь не менее 10 000 неизвестных на процесс.

или числовые факторы:

Параллельные прекондиционеры часто слабее своих серийных аналогов. Например, блок Якоби становится слабее, чем больше блоков вы используете. Таким образом, вам необходимо учитывать дополнительное время, затрачиваемое на дополнительные линейные итерации. Нелинейные условия в целом не работают таким образом, поэтому итерации Ньютона часто постоянны.

Мэтт Кнепли
источник
8

Всякий раз, когда вы пытаетесь распараллелить программу, вы должны сбалансировать ряд затрат, но в первую очередь есть

  • Стоимость выполнения каждого вычисления
  • Стоимость любых коммуникаций между этими вычислениями
  • Стоимость управления этими вычислениями

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

Если у вас есть взаимозависимости между вычислениями, стоимость связи может значительно возрасти. Если у вас есть сложный алгоритм, для выполнения которого требуется различное время, то сложность управления возрастает, когда вы пытаетесь эффективно использовать имеющиеся у вас ресурсы.

Как и в любой форме оптимизации, ключ заключается в тестировании. Посмотрите, как он работает без MPI, как он работает с MPI и одним процессом, а затем посмотрите, как он масштабируется.

Если вы играете с CUDA, попробуйте дать ему гораздо больше данных. Один тест здесь привел к отрицательному ускорению. Мы дали ему в 1000 раз больше данных, и версия GP-GPU завершилась почти за то же время, в то время как версия, работающая на главном ЦП, заняла в 1000 раз больше времени.

Марк Бут
источник
3

Я бы порекомендовал вам сделать следующее:

  • Создайте профиль времени выполнения вашего кода с параллелизацией и без него. Если у вас есть сомнения относительно того, как это сделать, мы можем помочь вам, если вы лучше описываете свой код.

  • Теперь вы можете сосредоточиться на частях, которые работают медленнее параллельно. Вы должны знать, что связь между процессами может быть медленной. Как отмечали Марк и Шон, то, что проблему можно разделить на потоки, не означает, что это будет эффективно. Вы должны изучить это более глубоко. Но если вы профилируете свой код, это может помочь вам найти любые существующие ошибки. Мои два цента.

Если вы объясните, что вы делаете более подробно, например, с помощью рабочего процесса, кто-то может дать вам лучшее объяснение.

jbcolmenares
источник
@ketch: ты прав. Извините и спасибо, что заметили. Отредактировал текст.
jbcolmenares