Introducción a la informática distribuida y en paralelo (6) Introducción a MPI

Sección 6 Introducción a MPI

Tucao: La lógica de enseñanza del profesor Luo es demasiado confusa. Se tarda el doble de tiempo en leer su PPT y la mitad del conocimiento en el libro de texto (la cantidad total es demasiado grande, pero la forma organizativa se puede utilizar como el valor efectivo del cerebro. Medio).

6.1 Por qué MPI?

(Por la tarea)

6.1.1 MPI dado OpenMP

El objetivo de MPI es alto rendimiento, gran escala y portabilidad.

El OpenMP que presentamos anteriormente es principalmente un sistema paralelo basado en memoria compartida, adecuado para el desarrollo de programas en paralelo en CPU de varios núcleos. MPI es una herramienta para redes y colaboración de múltiples hosts (por supuesto, también puede usarse de manera relativamente ineficiente para la computación de múltiples núcleos en un solo host).

Aunque la escritura de MPI es relativamente problemática y la eficiencia en paralelo es relativamente baja debido a la coordinación de la comunicación entre procesos, pero debido a que puede coordinar la computación en paralelo entre hosts, es extremadamente escalable en escala paralela desde PC Puede ir a una supercomputadora.

Con todo, OpenMP está diseñado para la computación de múltiples subprocesos en un solo host (solo funciona en un solo host), mientras que MPI está diseñado para la colaboración de múltiples hosts.

6.1.2 Por qué debería comprender MPI

MPI es el estándar de biblioteca MP más importante. Si bien puede ser más conveniente tener algunas de las bibliotecas más modernas, aprender MPI aún lo ayuda a comprender mejor la comunicación colectiva ( concepto de comunicación grupal ) de

6.2 Explicación básica de MPI

Primero tengamos un HelloWorld

#include <mpi.h>
int main(int argc, char *argv[])
{
    int npes, myrank;
    MPI_Init(&argc, &argv);//初始化MPI
    MPI_Comm_size(MPI_COMM_WORLD, &npes);//npes获得通信域中的进程总数
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);//myrank获得本进程的序号
    printf("From process %d out of %d, Hello World!\n",myrank, npes);
    MPI_Finalize();//结束MPI
    return 0;
}

A diferencia de OpenMP, MPI no desensambla la tarea de un determinado bloque de código, sino que es una herramienta para que el programador dirija la ejecución de diferentes procesadores después de dividir la tarea. Todos los procesadores ejecutarán el mismo código, y es el número de proceso lo que distingue el formulario de tarea específico.

  • Por ejemplo, cuando el método del tamiz encuentra números primos, la matriz de longitud 1000 se divide por igual en 10 segmentos y el k-ésimo proceso procesa el k-ésimo segmento, es decir, el subíndice es de (k - 1) ∗ 100 + 1 (k-1) * 100 + 1( k-1 )1 0 0+1 hastak ∗ 100 k * 100k1 0 0 parte

6.2.1 Archivo de encabezado

#include<mpi.h>

6.2.2 Funciones básicas de la biblioteca

int MPI_Init(int*argc,char***argv);//初始化MPI环境,必须出现在其他MPI函数之前
int MPI_Finalize();//结束MPI环境(执行各种clean-up tasks)
int MPI_Comm_size(MPI_COMM comm, int *size);//size对应位置获得通信域中的进程总数
int MPI_Comm_rank(MPI_COMM comm, int *rank);//rank对应位置获得当前进程的序号

(El llamado dominio de comunicación es una colección de procesadores que pueden transmitirse mensajes entre sí)

6.2.3 Compilar

mpicc -o name example.c
mpic++ -o name example.cpp

Compile el código en el ejemplo y guarde el programa ejecutable en el archivo de nombre

6.2.4 Ejecución

Especifique el número de procesos

mpirun -np number name

Generar procesos numéricos para ejecutar nombre

Especifique el procesador host

Considere usar --host y --hostfile cuando sea necesario

Múltiples programas de datos múltiples (MPMD)

mpirun-np 1 master : -np 7 slave

En el ejemplo anterior, el comando cmd expande un total de ocho procesos para dos programas de ejecución completamente diferentes. Estos programas de ejecución estarán en el mismo dominio de comunicación (es decir, pueden comunicarse entre sí a través de MPI)

6.2.5 Enviar y recibir

Bloqueo sin búfer

Para la transmisión de información, el modo más simple (y más seguro) de enviar y recibir es que el remitente y el receptor pueden ejecutar después de determinar el estado del otro.

El remitente enviará una solicitud de envío, y el receptor enviará un mensaje que permite la solicitud. Solo cuando los dos estén conectados, se enviarán los datos. En otras palabras, ya sea un receptor o un remitente,Lo que se ejecuta primero debe ejecutarse después de esperarde.

El llamado bloqueo sin búfer se refiere a

  • Una vez que el remitente comienza a ejecutarse, debe esperar el permiso del receptor para enviar. Después de obtener el permiso, el remitente puede regresar después de completar el envío. El proceso original se detiene en el remitente durante el período desde el inicio del remitente hasta la devolución.
  • Una vez que el receptor comienza a ejecutarse, solo esperando que el remitente esté listo para enviar la solicitud, el receptor puede regresar después de completar la recepción El proceso original se detiene en el receptor durante el período desde el inicio del receptor hasta el regreso.

Desventajas: se generará una gran cantidad de sobrecarga inactiva (a menos que los dos se ejecuten exactamente al mismo tiempo)

bloqueo en búfer

También hay un modo de envío y recepción: el remitente copia directamente los datos al búfer del proceso de recepción y el receptor copia directamente los datos del búfer del proceso.

La caché (almacenamiento en búfer) en realidad reemplaza la sobrecarga inactiva con la sobrecarga de copia en búfer.

  • Cuando el extremo receptor no tiene el hardware de comunicación relevante, el remitenteinterrumpirEl proceso del extremo receptor copia los datos al búfer del proceso receptor.
  • El extremo receptor aún debe esperar a que el remitente envíe algo para continuar.

Sin bloqueo

Independientemente de si el modo sin bloqueo es seguro o no, la instrucción subsiguiente continuará ejecutándose después de que se envíe la solicitud, y la instrucción subsiguiente se ejecutará después de que se envíe la solicitud. Cuando la solicitud y el permiso coinciden, enviar y recibir se ejecutan formalmente

  • Para el modo sin bloqueo sin búfer , los peligros potenciales se encuentran principalmente en dos aspectos: el programa posterior en el remitente puedeCambiar los datos que se enviarán antes de enviar, Lo que lleva al hecho de que los datos enviados oficialmente son realmente incorrectos; los procedimientos posteriores en el extremo receptor puedenVisita antes de recibirDatos a recibir.

El uso del modo sin bloqueo requiere que los programadores comprendan y dominen bien el contenido del programa

Las bibliotecas de paso de mensajes generalmente proporcionan primitivas de bloqueo y no bloqueo

Modo de envío de MPI

int MPI_Send(
    void *message,//被传送数据的起始地址
    int count,//被传送的数据项个数
    MPI_Datatype datatype,//被传送的数据类型
    int dest,//接收进程号
    int tag,//信息的标记(可以说明用途)
    MPI_Comm comm//通信域
);

Sigue el modo de bloqueo,Solo se puede usar el búfer de envíoCuando (por ejemplo, los datos se han enviado de forma segura al búfer de recepción o al búfer intermedio) antes de regresar. En términos generales, el sistema copiará estos mensajes al búfer del sistema.

Algunos otros métodos de envío que se pueden considerar (comprenda los métodos relevantes y luego considere los detalles cuando los use)

  • MPI_Send:
  • MPI_Bsend: regresa inmediatamente
  • MPI_Ssend: regresa solo después de hacer coincidir el receptor
  • MPI_Rsend: Esta oración se usa solo cuando se determina que el receptor correspondiente debe estar en espera; en este caso especial, el remitente proporcionará alguna información al sistema, lo que puede reducir algunos gastos generales
  • MPI_Isend: cumple con el modo sin bloqueo, pero no puede volver a utilizar el búfer de envío inmediatamente

Modo de recepción de MPI

int MPI_Recv( 
    void *message,//要被存放的起始位置
    int count,//能接收的最大数目
    MPI_Datatype datatype,//接收的数据类型
    int source,//发送进程号
    int tag,//信息的标记(可以说明用途)
    MPI_Comm comm,//通信域
    MPI_Status *status//一条类型为MPI_Status的记录,Recv完成后,可以访问status获得函数相关的状态信息
);

En particular, los siguientes elementos se pueden obtener del estado

  • estado-> MPI_source enviar número de proceso
  • status-> MPI_tag La etiqueta del mensaje recibido
  • status-> condición de error MPI_ERROR
¿Por qué existe un estado?
  • La fuente en MPI_Recv generalmente se establece en la constante MPI_ANY_SOURCE para recibir información de cualquier fuente
  • La etiqueta en MPI_Recv generalmente se establece en la constante MPI_ANY_TAG para recibir cualquier información de etiqueta

En el caso de no restringir la fuente de envío y la etiqueta de envío, es necesario verificar el registro de estado (estado) para determinar el proceso de envío o el valor de la etiqueta de una información específica

Además, hay una función de ayuda

int MPI_Get_count(MPI_Status* status,MPI_Datatype datatype,int* count);

La función auxiliar puede dar el número específico de elementos de datos
recibidos (la función de recepción solo da la capacidad máxima al extremo receptor, por lo que determinar el número específico de datos recibidos también es un asunto por resolver)

Supongo que te gusta

Origin blog.csdn.net/Kaiser_syndrom/article/details/105361466
Recomendado
Clasificación