MPI_Isend: как сохранить данные до их получения?

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

В настоящее время я делаю что-то вроде этого:

vector<int*> outbox;
vector<MPI_Request> stats;

void run()
{
while (!done())
{
//some magic
//...

sendMsg(rand(), getRecipRank());
}
}

void sendMsg(int n, int recipRank)
{
//Need to gen n random integers and send it to proc with rank recipRank
//Can't block until the numbers are reveived.
//So how do I make sure these numbers are safe until then?int* data = (int*)malloc(sizeof(int) * n);
//fill the data array with random numbers here

MPI_Request req;
MPI_Isend(data, n, MPI_INT, recipRank, 0, MPI_COMM_WORLD, &req);

//Keeping the pointer to the array to free it later
outbox.push_back(data); //Does this help keep the data safe until they're received?
stats.push_back(req);
}

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

Я проверил это с небольшим количеством сообщений, и это, кажется, работает, но я не уверен, что это будет ВСЕГДА работать или мне просто везет.

2

Решение

Выглядит хорошо! Если вы выделяете память, используя malloc никто не будет связываться с этим, кроме вас. Так как вы не будете связываться, это будет безопасно.

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

Просто чтобы уточнить: ваши данные не «безопаснее», потому что вы помещаете их в вектор outboxбыло бы безопасно даже без этого. Вы помещаете это в вектор, чтобы иметь возможность освободить это позже.

2

Другие решения

Это прекрасно работает, но вам даже не нужно прибегать к C-malloc,

Вы можете безопасно использовать конструкции C ++, такие как:

  • new[] указатели в std::vector<int*>
  • std::vector<std::unique_ptr<int[]>> (Я бы предпочел, чтобы в вашей ситуации)
  • std::vector::data() векторов в векторах. Для этого, однако, убедитесь, что не вызываете неконстантные методы для векторов, которые предоставляют память, вызываемую до тех пор, пока запрос не будет завершен.

Было бы не быть безопасным в использовании std::vector<int[10]> outbox или же std::vector<std::array<int, 10>> outbox поскольку эта память будет относиться непосредственно к исходящему вектору, который может быть перераспределен (изменен в размерах) при последующих вызовах push_back, Но это важно только для времени компиляции n, std::vector<std::unique_ptr<std::array<int, 10>>> было бы хорошо снова.

0

По вопросам рекламы [email protected]