Я должен отправить много сообщений, используя 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
,
Я проверил это с небольшим количеством сообщений, и это, кажется, работает, но я не уверен, что это будет ВСЕГДА работать или мне просто везет.
Выглядит хорошо! Если вы выделяете память, используя malloc
никто не будет связываться с этим, кроме вас. Так как вы не будете связываться, это будет безопасно.
Это хороший шаблон для чередования вычислений и коммуникации, используя больше памяти. Если вы хотите ограничить использование памяти, вы можете установить максимальную длину для вектора. outbox
и начните использовать блокирующие посылки, когда эта длина будет достигнута.
Просто чтобы уточнить: ваши данные не «безопаснее», потому что вы помещаете их в вектор outbox
было бы безопасно даже без этого. Вы помещаете это в вектор, чтобы иметь возможность освободить это позже.
Это прекрасно работает, но вам даже не нужно прибегать к 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>>>
было бы хорошо снова.