Джефф абсолютно прав насчет единственного способа убедиться в том, что он измеряет - в конце концов, мы ученые, и это эмпирический вопрос - и дает отличный совет о том, как проводить такие измерения. Позвольте мне теперь предложить противоположное (или, может быть, дополнительное) мнение.
Необходимо сделать различие между написанием кода, который будет широко использоваться, и настройкой его для конкретной цели. В общем, мы делаем первое - строим наш код так, чтобы: а) мы могли использовать его на самых разных платформах, и б) код можно было поддерживать и расширять на долгие годы. Но иногда мы делаем другое - у нас есть годовой объем распределения на какой-то большой машине, и мы наращиваем некоторый необходимый набор больших симуляций, и нам нужен определенный базовый уровень производительности, чтобы получить то, что нам нужно сделать во время время предоставленного распределения.
Когда мы пишем код, сделать его широко применимым и обслуживаемым гораздо важнее, чем сэкономить несколько процентов времени выполнения на конкретной машине. В этом случае правильным решением будет почти всегда использовать процедуру, которая наилучшим образом описывает то, что вы хотите сделать - это, как правило, самый конкретный вызов, который вы можете сделать, который делает то, что вы хотите. Например, если прямой allgather или allgatherv делает то, что вы хотите, вы должны использовать это, а не выкатывать свои собственные из операций разброса / сбора. Причины таковы:
- Теперь код более четко отражает то, что вы пытаетесь сделать, делая его более понятным для следующего человека, который придет к вашему коду в следующем году, не имея представления о том, что должен делать код (этот человек вполне может быть вами);
- Для этого более конкретного случая доступны оптимизации на уровне MPI, которых нет в более общем случае, поэтому ваша библиотека MPI может вам помочь; и
- Попытка свернуть свою собственную, скорее всего, будет иметь неприятные последствия; даже если он работает лучше на компьютере X с реализацией MPI Y.ZZ, он может работать намного хуже, когда вы переходите на другую машину или обновляете реализацию MPI.
В этом довольно распространенном случае, если вы обнаружите, что некоторый коллектив MPI работает на вашем компьютере неоправданно медленно, лучше всего подать отчет об ошибке поставщику mpi; Вы не хотите усложнять свое собственное программное обеспечение, пытаясь обойти код приложения, что должно быть исправлено на уровне библиотеки MPI.
Однако . Если вы находитесь в режиме «настройки» - у вас есть рабочий код, вам нужно увеличить очень большие масштабы за короткий промежуток времени (например, годичное распределение), и вы профилировали свой код и обнаружил, что эта конкретная часть вашего кода является узким местом, тогда имеет смысл начать выполнять эти очень специфические настройки. Надеемся, что они не будут долгосрочными частями вашего кода - в идеале эти изменения останутся в какой-то конкретной ветке вашего репозитория - но вам, возможно, придется сделать это. В этом случае кодирование двух разных подходов, отличающихся директивами препроцессора, или подход «автонастройки» для конкретного шаблона связи - может иметь большой смысл.
Так что я не согласен с Джеффом, я просто хочу добавить некоторый контекст о том, когда вы должны быть достаточно обеспокоены такими относительными вопросами производительности, чтобы изменить свой код, чтобы справиться с ним.
MPI_Scatter
сопровождаемыйMPI_Gather
не обеспечивает такую же семантику связи, какMPI_Allgather
. Возможно, существует избыточность, когда вы выражаете операцию любым способом?