tutorial receive programming open for example synchronization mpi openmpi

synchronization - programming - receive mpi



¿Cuándo necesito usar MPI_Barrier()? (3)

Me pregunto cuando necesito usar barrera? ¿Lo necesito antes / después de una dispersión / recopilación, por ejemplo? ¿O debería OMPI asegurarse de que todos los procesos hayan llegado a ese punto antes de dispersar / reunir? De manera similar, después de una transmisión, ¿puedo esperar que todos los procesos ya reciban el mensaje?


May MPI_Barrier () no se usa a menudo, pero es útil. De hecho, incluso si utilizara la comunicación síncrona, el MPI_Send / Recv () solo puede asegurarse de que los dos procesos estén sincronizados. En mi proyecto, un proyecto cuda + MPI, todo lo que usé es comunicación asíncrona. Descubrí que, en algunos casos, si no uso el MPI_Barrier () seguido de la función Wait (), es muy probable que ocurra la situación de que dos procesos (gpu) se transmitan datos entre sí al mismo tiempo, lo que podría Reducir la eficiencia del programa. El bicho de arriba siempre me hace enojar y me toma unos días para encontrarlo. Por lo tanto, puede pensar detenidamente si usa MPI_Barrier () cuando usó MPI_Isend / Irecv en su programa. A veces, la sincronización de los procesos no solo es necesaria sino que también DEBE, especialmente su programa está tratando con el dispositivo.


Todas las operaciones colectivas en MPI antes de MPI-3.0 se están bloqueando, lo que significa que es seguro usar todos los buffers que se les pasan después de que regresen. En particular, esto significa que todos los datos se recibieron cuando una de estas funciones regresa. (Sin embargo, no implica que todos los datos hayan sido enviados). Por lo tanto, MPI_Barrier no es necesario (o es muy útil) antes / después de las operaciones colectivas, si todos los búferes ya son válidos.

Tenga en cuenta también que MPI_Barrier no espera mágicamente las llamadas no bloqueadas. Si utiliza un envío / recepción no bloqueante y ambos procesos esperan en un MPI_Barrier después del par de envío / recepción, no se garantiza que los procesos hayan enviado / recibido todos los datos después del MPI_Barrier. Utilice MPI_Wait (y amigos) en su lugar. Así que la siguiente pieza de código contiene errores:

/* ERRORNOUS CODE */ Code for Process 0: Process 0 sends something using MPI_Isend MPI_Barrier(MPI_COMM_WORLD); Process 0 uses buffer passed to MPI_Isend // (!) Code for Process 1: Process 1 recvs something using MPI_Irecv MPI_Barrier(MPI_COMM_WORLD); Process 1 uses buffer passed to MPI_Irecv // (!)

Ambas líneas que están marcadas con (!) Son inseguras!

MPI_Barrier solo es útil en un puñado de casos. La mayoría de las veces no te importa si tus procesos se sincronizan. Mejor leer acerca de bloquear y no bloquear llamadas!


Un uso de MPI_Barrier es, por ejemplo, controlar el acceso a un recurso externo como el sistema de archivos, al que no se accede mediante MPI. Por ejemplo, si quieres que cada proceso escriba cosas en un archivo en secuencia, podrías hacerlo así:

int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); for ( int ii = 0; ii < size; ++ii ) { if ( rank == ii ) { // my turn to write to the file writeStuffToTheFile(); } MPI_Barrier(MPI_COMM_WORLD); }

De esa manera, puede estar seguro de que no hay dos procesos que estén llamando simultáneamente a writeStuffToTheFile .