C ++ MPI, используя несколько узлов, сначала уменьшают на уровне узла, а затем уменьшают до головного узла - PullRequest
0 голосов
/ 01 июля 2019

Я использую кластер Windows HPC с 12 узлами (каждый с 24 ядрами) для запуска программы C ++ MPI (используйте Boost MPI).Один прогон с уменьшением MPI, один комментарий - уменьшение MPI (только для теста скорости).Время выполнения - 01:17:23 и 01:03:49.Мне кажется, что снижение MPI занимает большую часть времени.Я думаю, что было бы целесообразно попытаться сначала уменьшить на уровне узла, а затем уменьшить до головного узла для повышения производительности.

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

#include <iostream>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
using namespace std;

int main()
{
  mpi::environment env;
  mpi::communicator world;

  int i = world.rank();


  boost::mpi::communicator local = world.split(world.rank()/2); // total 8 cores, divide in 4 groups
  boost::mpi::communicator heads = world.split(world.rank()%4);

  int res = 0;

  boost::mpi::reduce(local, i, res, std::plus<int>(), 0);
  if(world.rank()%2==0)
  cout<<res<<endl;
  boost::mpi::reduce(heads, res, res, std::plus<int>(), 0);

  if(world.rank()==0)
      cout<<res<<endl;

  return 0;
}

Вывод нечеткий, что-то вроде этого

Z
h
h
h
h
a
a
a
a
n
n
n
n
g
g
g
g
\
\
\
\
b
b
b
b
o
o
o
o
o
o
o
o
s
...
...
...

Сообщение об ошибке

Test.exe ended prematurely and may have crashed. exit code 3

Я подозреваю, что я сделал что-то не так с групповым разделением / сокращением, но не могу понять это с помощью нескольких испытаний. Как я могу изменить это, чтобы сделать эту работу?Спасибо.

1 Ответ

1 голос
/ 03 июля 2019

Причина получения наличных заключается в том, что вы передаете одну и ту же переменную дважды в MPI в следующей строке

boost::mpi::reduce(heads, res, res, std::plus<int>(), 0);

Это не совсем хорошо документировано в Boost.MPI, но boost принимает их по ссылке и передает соответствующие указатели в MPI. MPI вообще запрещает вам передавать один и тот же буфер дважды на один и тот же вызов. Точнее, выходной буфер, передаваемый в функцию MPI, не должен иметь псевдоним (перекрытие) с любым другим буфером, передаваемым в этом вызове.

Вы можете легко исправить это, создав копию res.

Я также думаю, что вы, вероятно, хотите ограничить вызов второго сокращения из процессов с local.rank() == 0.

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

...