Sistemas de Operação II. Ricardo Rocha

Texto

(1)

Sistemas de Opera¸ c˜ ao II

Programa¸ c˜ ao em Mem´ oria Distribu´ıda

Ricardo Rocha

ricroc@dcc.fc.up.pt

(2)

Programa¸ c˜ ao em Mem´ oria Distribu´ıda

➤ As aplica¸ c˜ oes s˜ ao vistas como um conjunto de programas que s˜ ao executados de forma independente em diferentes processadores de diferentes computadores.

A semˆ antica da aplica¸c˜ ao ´ e mantida por troca de informa¸ c˜ ao entre os v´ arios

programas.

(3)

Programa¸ c˜ ao em Mem´ oria Distribu´ıda

➤ As aplica¸ c˜ oes s˜ ao vistas como um conjunto de programas que s˜ ao executados de forma independente em diferentes processadores de diferentes computadores.

A semˆ antica da aplica¸c˜ ao ´ e mantida por troca de informa¸ c˜ ao entre os v´ arios programas.

➤ A sincroniza¸ c˜ ao e o modo de funcionamento da aplica¸ c˜ ao ´ e da responsabilidade

do programador. No entanto, o programador n˜ ao quer desperdi¸ car muito tempo

com os aspectos relacionados com a comunica¸ c˜ ao propriamente dita.

(4)

Programa¸ c˜ ao em Mem´ oria Distribu´ıda

➤ As aplica¸ c˜ oes s˜ ao vistas como um conjunto de programas que s˜ ao executados de forma independente em diferentes processadores de diferentes computadores.

A semˆ antica da aplica¸c˜ ao ´ e mantida por troca de informa¸ c˜ ao entre os v´ arios programas.

➤ A sincroniza¸ c˜ ao e o modo de funcionamento da aplica¸ c˜ ao ´ e da responsabilidade do programador. No entanto, o programador n˜ ao quer desperdi¸ car muito tempo com os aspectos relacionados com a comunica¸ c˜ ao propriamente dita.

➤ Existem diferentes bibliotecas que implementam os pormenores da comunica¸c˜ ao.

Essas bibliotecas permitem executar programas remotamente, monitorizar o seu estado, e trocar informa¸ c˜ ao entre os diferentes programas, sem que o programador precise de saber explicitamente como isso ´ e conseguido.

1

(5)

Message-Passing Interface (MPI)

O que n˜ ao ´ e o MPI:

(6)

Message-Passing Interface (MPI)

O que n˜ ao ´ e o MPI:

➤ O MPI n˜ ao ´ e um modelo revolucion´ ario de programar m´ aquinas paralelas. Pelo

contr´ ario, ele ´ e um modelo de programa¸ c˜ ao paralela baseado na troca de

mensagens que pretendeu recolher as melhores funcionalidades dos sistemas

existentes, aperfei¸ co´ a-las e torn´ a-las um standard.

(7)

Message-Passing Interface (MPI)

O que n˜ ao ´ e o MPI:

➤ O MPI n˜ ao ´ e um modelo revolucion´ ario de programar m´ aquinas paralelas. Pelo contr´ ario, ele ´ e um modelo de programa¸ c˜ ao paralela baseado na troca de mensagens que pretendeu recolher as melhores funcionalidades dos sistemas existentes, aperfei¸ co´ a-las e torn´ a-las um standard.

➤ O MPI n˜ ao ´ e uma linguagem de programa¸ c˜ ao. ´ E um conjunto de rotinas

(biblioteca) definido para ser usado em programas C ou Fortran.

(8)

Message-Passing Interface (MPI)

O que n˜ ao ´ e o MPI:

➤ O MPI n˜ ao ´ e um modelo revolucion´ ario de programar m´ aquinas paralelas. Pelo contr´ ario, ele ´ e um modelo de programa¸ c˜ ao paralela baseado na troca de mensagens que pretendeu recolher as melhores funcionalidades dos sistemas existentes, aperfei¸ co´ a-las e torn´ a-las um standard.

➤ O MPI n˜ ao ´ e uma linguagem de programa¸ c˜ ao. ´ E um conjunto de rotinas (biblioteca) definido para ser usado em programas C ou Fortran.

➤ O MPI n˜ ao ´ e a implementa¸ c˜ ao. ´ E apenas a especifica¸ c˜ ao!

(9)

Message-Passing Interface (MPI)

O que n˜ ao ´ e o MPI:

➤ O MPI n˜ ao ´ e um modelo revolucion´ ario de programar m´ aquinas paralelas. Pelo contr´ ario, ele ´ e um modelo de programa¸ c˜ ao paralela baseado na troca de mensagens que pretendeu recolher as melhores funcionalidades dos sistemas existentes, aperfei¸ co´ a-las e torn´ a-las um standard.

➤ O MPI n˜ ao ´ e uma linguagem de programa¸ c˜ ao. ´ E um conjunto de rotinas (biblioteca) definido para ser usado em programas C ou Fortran.

➤ O MPI n˜ ao ´ e a implementa¸ c˜ ao. ´ E apenas a especifica¸ c˜ ao!

Principais objectivos:

➤ Aumentar a portabilidade dos programas.

➤ Aumentar e melhorar a funcionalidade.

➤ Conseguir implementa¸ c˜ oes eficientes numa vasta gama de arquitecturas.

➤ Suportar ambientes heterog´ eneos.

2

(10)

Um Pouco de Hist´ oria

➤ O MPI nasceu em 1992 da coopera¸ c˜ ao entre universidades, empresas e utilizado- res dos Estados Unidos e Europa (MPI Forum – http://www.mpi-forum.org) e foi publicado em Abril de 1994.

➤ Principais implementa¸ c˜ oes:

♦ LAM

http://www.lam-mpi.org

♦ MPICH

http://www.mcs.anl.gov/mpi/mpich

♦ CHIMP

http://www.epcc.ed.ac.uk/chimp

➤ Propostas de extens˜ ao foram entretanto estudadas e desenvolvidas:

♦ MPI-2

♦ MPI-IO

3

(11)

Single Program Multiple Data (SPMD)

➤ SPMD ´ e um modelo de programa¸ c˜ ao em que os v´ arios programas que constituem a aplica¸ c˜ ao s˜ ao incorporados num ´ unico execut´ avel.

➤ Cada processo executa uma c´ opia desse execut´ avel. Utilizando condi¸ c˜ oes de teste sobre o ranking dos processos, diferentes processos executam diferentes partes do programa.

...

if (my_rank == 0) { // c´ odigo tarefa 0 } ...

...

} else if (my_rank == N) { // c´ odigo tarefa N

} ...

➤ O MPI n˜ ao imp˜ oe qualquer restri¸ c˜ ao quanto ao modelo de programa¸ c˜ ao (isso depende do suporte oferecido por cada implementa¸ c˜ ao particular). Sendo assim, o modelo SPMD ´ e aquele que oferece a aproxima¸ c˜ ao mais port´ avel.

4

(12)

Iniciar e Terminar o Ambiente de Execu¸ c˜ ao do MPI

MPI Init(int *argc, char ***argv)

➤ MPI Init() inicia o ambiente de execu¸ c˜ ao do MPI.

(13)

Iniciar e Terminar o Ambiente de Execu¸ c˜ ao do MPI

MPI Init(int *argc, char ***argv)

➤ MPI Init() inicia o ambiente de execu¸ c˜ ao do MPI.

MPI Finalize(void)

➤ MPI Finalize() termina o ambiente de execu¸ c˜ ao do MPI.

(14)

Iniciar e Terminar o Ambiente de Execu¸ c˜ ao do MPI

MPI Init(int *argc, char ***argv)

➤ MPI Init() inicia o ambiente de execu¸ c˜ ao do MPI.

MPI Finalize(void)

➤ MPI Finalize() termina o ambiente de execu¸ c˜ ao do MPI.

➤ Todas as fun¸ c˜ oes MPI retornam 0 se OK, valor positivo se erro.

5

(15)

Estrutura Base de um Programa MPI

// incluir a biblioteca de fun¸ c~ oes MPI

#include "mpi.h"

...

main(int argc, char **argv) { ...

// nenhuma chamada a fun¸ c~ oes MPI antes deste ponto MPI_Init(&argc, &argv);

...

MPI_Finalize();

// nenhuma chamada a fun¸ c~ oes MPI depois deste ponto ...

}

6

(16)

Comunicadores

➤ Uma aplica¸c˜ ao MPI vˆ e o seu ambiente de execu¸ c˜ ao paralelo como um conjunto de grupos de processos.

➤ O comunicador ´ e a estrutura de dados MPI que abstrai o conceito de grupo e define quais os processos que podem trocar mensagens entre si. Todas as fun¸ c˜ oes de comunica¸ c˜ ao tˆ em um argumento relativo ao comunicador.

0 1

2 3

Comunicador Processo

➤ Por defeito, o ambiente de execu¸ c˜ ao do MPI define um comunicador universal (MPI COMM WORLD) que engloba todos os processos em execu¸ c˜ ao.

➤ Todos os processos possuem um identificador ´ unico (rank) que determina a sua posi¸ c˜ ao (de 0 a N-1) no comunicador. Se um processo pertencer a mais do que um comunicador ele pode ter rankings diferentes em cada um deles.

7

(17)

Informa¸ c˜ ao Relativa a um Comunicador

MPI Comm rank(MPI Comm comm, int *rank)

➤ MPI Comm rank() devolve em rank a posi¸ c˜ ao do processo corrente no comuni-

cador comm.

(18)

Informa¸ c˜ ao Relativa a um Comunicador

MPI Comm rank(MPI Comm comm, int *rank)

➤ MPI Comm rank() devolve em rank a posi¸ c˜ ao do processo corrente no comuni- cador comm.

MPI Comm size(MPI Comm comm, int *size)

➤ MPI Comm size() devolve em size o total de processos no comunicador comm.

8

(19)

Mensagens MPI

➤ Na sua essˆ encia, as mensagens n˜ ao s˜ ao nada mais do que pacotes de informa¸c˜ ao

trocados entre processos.

(20)

Mensagens MPI

➤ Na sua essˆ encia, as mensagens n˜ ao s˜ ao nada mais do que pacotes de informa¸c˜ ao trocados entre processos.

➤ Para efectuar uma troca de mensagens, o ambiente de execu¸ c˜ ao necessita de

conhecer no m´ınimo a seguinte informa¸ c˜ ao:

(21)

Mensagens MPI

➤ Na sua essˆ encia, as mensagens n˜ ao s˜ ao nada mais do que pacotes de informa¸c˜ ao trocados entre processos.

➤ Para efectuar uma troca de mensagens, o ambiente de execu¸ c˜ ao necessita de conhecer no m´ınimo a seguinte informa¸ c˜ ao:

♦ Processo que envia.

♦ Processo que recebe.

♦ Localiza¸ c˜ ao dos dados na origem.

♦ Localiza¸ c˜ ao dos dados no destino.

♦ Tamanho dos dados.

♦ Tipo dos dados.

(22)

Mensagens MPI

➤ Na sua essˆ encia, as mensagens n˜ ao s˜ ao nada mais do que pacotes de informa¸c˜ ao trocados entre processos.

➤ Para efectuar uma troca de mensagens, o ambiente de execu¸ c˜ ao necessita de conhecer no m´ınimo a seguinte informa¸ c˜ ao:

♦ Processo que envia.

♦ Processo que recebe.

♦ Localiza¸ c˜ ao dos dados na origem.

♦ Localiza¸ c˜ ao dos dados no destino.

♦ Tamanho dos dados.

♦ Tipo dos dados.

➤ O tipo dos dados ´ e um dos itens mais relevantes nas mensagens MPI. Da´ı, uma mensagem MPI ser normalmente designada como uma sequˆ encia de tipo de dados.

9

(23)

Tipos de Dados B´ asicos

MPI C

MPI CHAR signed char

MPI SHORT signed short int

MPI INT signed int

MPI LONG signed long int

MPI UNSIGNED CHAR unsigned char

MPI UNSIGNED SHORT unsigned short int MPI UNSIGNED unsigned int

MPI UNSIGNED LONG unsigned long int

MPI FLOAT float

MPI DOUBLE double

MPI LONG DOUBLE long double MPI PACKED

10

(24)

Envio Standard de Mensagens

MPI Send(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ MPI Send() ´ e a funcionalidade b´ asica para envio de mensagens.

(25)

Envio Standard de Mensagens

MPI Send(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ MPI Send() ´ e a funcionalidade b´ asica para envio de mensagens.

➤ buf ´ e o endere¸ co inicial dos dados a enviar.

(26)

Envio Standard de Mensagens

MPI Send(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ MPI Send() ´ e a funcionalidade b´ asica para envio de mensagens.

➤ buf ´ e o endere¸ co inicial dos dados a enviar.

➤ count ´ e o n´ umero de elementos do tipo datatype a enviar.

(27)

Envio Standard de Mensagens

MPI Send(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ MPI Send() ´ e a funcionalidade b´ asica para envio de mensagens.

➤ buf ´ e o endere¸ co inicial dos dados a enviar.

➤ count ´ e o n´ umero de elementos do tipo datatype a enviar.

➤ datatype ´ e o tipo de dados a enviar.

(28)

Envio Standard de Mensagens

MPI Send(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ MPI Send() ´ e a funcionalidade b´ asica para envio de mensagens.

➤ buf ´ e o endere¸ co inicial dos dados a enviar.

➤ count ´ e o n´ umero de elementos do tipo datatype a enviar.

➤ datatype ´ e o tipo de dados a enviar.

➤ dest ´ e a posi¸ c˜ ao do processo, no comunicador comm, a quem se destina a

mensagem.

(29)

Envio Standard de Mensagens

MPI Send(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ MPI Send() ´ e a funcionalidade b´ asica para envio de mensagens.

➤ buf ´ e o endere¸ co inicial dos dados a enviar.

➤ count ´ e o n´ umero de elementos do tipo datatype a enviar.

➤ datatype ´ e o tipo de dados a enviar.

➤ dest ´ e a posi¸ c˜ ao do processo, no comunicador comm, a quem se destina a mensagem.

➤ tag ´ e uma marca que identifica a mensagem a enviar. As mensagens podem

possuir idˆ enticas ou diferentes marcas por forma a que o processo que as

envia/recebe as possa agrupar/diferenciar em classes.

(30)

Envio Standard de Mensagens

MPI Send(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ MPI Send() ´ e a funcionalidade b´ asica para envio de mensagens.

➤ buf ´ e o endere¸ co inicial dos dados a enviar.

➤ count ´ e o n´ umero de elementos do tipo datatype a enviar.

➤ datatype ´ e o tipo de dados a enviar.

➤ dest ´ e a posi¸ c˜ ao do processo, no comunicador comm, a quem se destina a mensagem.

➤ tag ´ e uma marca que identifica a mensagem a enviar. As mensagens podem possuir idˆ enticas ou diferentes marcas por forma a que o processo que as envia/recebe as possa agrupar/diferenciar em classes.

➤ comm ´ e o comunicador dos processos envolvidos na comunica¸ c˜ ao.

11

(31)

Recep¸ c˜ ao Standard de Mensagens

MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Status *status)

➤ MPI Recv() ´ e a funcionalidade b´ asica para recep¸ c˜ ao de mensagens.

(32)

Recep¸ c˜ ao Standard de Mensagens

MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Status *status)

➤ MPI Recv() ´ e a funcionalidade b´ asica para recep¸ c˜ ao de mensagens.

➤ buf ´ e o endere¸ co onde devem ser colocados os dados recebidos.

(33)

Recep¸ c˜ ao Standard de Mensagens

MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Status *status)

➤ MPI Recv() ´ e a funcionalidade b´ asica para recep¸ c˜ ao de mensagens.

➤ buf ´ e o endere¸ co onde devem ser colocados os dados recebidos.

➤ count ´ e o n´ umero m´ aximo de elementos do tipo datatype a receber (tem de ser

maior ou igual ao n´ umero de elementos enviados).

(34)

Recep¸ c˜ ao Standard de Mensagens

MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Status *status)

➤ MPI Recv() ´ e a funcionalidade b´ asica para recep¸ c˜ ao de mensagens.

➤ buf ´ e o endere¸ co onde devem ser colocados os dados recebidos.

➤ count ´ e o n´ umero m´ aximo de elementos do tipo datatype a receber (tem de ser maior ou igual ao n´ umero de elementos enviados).

➤ datatype ´ e o tipo de dados a receber (n˜ ao necessita de corresponder aos dados que foram enviados).

12

(35)

Recep¸ c˜ ao Standard de Mensagens

MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Status *status)

➤ source ´ e a posi¸ c˜ ao do processo, no comunicador comm, de quem se pretende

receber a mensagem. Pode ser MPI ANY SOURCE para receber de qualquer

processo no comunicador comm.

(36)

Recep¸ c˜ ao Standard de Mensagens

MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Status *status)

➤ source ´ e a posi¸ c˜ ao do processo, no comunicador comm, de quem se pretende receber a mensagem. Pode ser MPI ANY SOURCE para receber de qualquer processo no comunicador comm.

➤ tag ´ e a marca que identifica a mensagem que se pretende receber. Pode ser

MPI ANY TAG para receber qualquer mensagem.

(37)

Recep¸ c˜ ao Standard de Mensagens

MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Status *status)

➤ source ´ e a posi¸ c˜ ao do processo, no comunicador comm, de quem se pretende receber a mensagem. Pode ser MPI ANY SOURCE para receber de qualquer processo no comunicador comm.

➤ tag ´ e a marca que identifica a mensagem que se pretende receber. Pode ser MPI ANY TAG para receber qualquer mensagem.

➤ comm ´ e o comunicador dos processos envolvidos na comunica¸ c˜ ao.

(38)

Recep¸ c˜ ao Standard de Mensagens

MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Status *status)

➤ source ´ e a posi¸ c˜ ao do processo, no comunicador comm, de quem se pretende receber a mensagem. Pode ser MPI ANY SOURCE para receber de qualquer processo no comunicador comm.

➤ tag ´ e a marca que identifica a mensagem que se pretende receber. Pode ser MPI ANY TAG para receber qualquer mensagem.

➤ comm ´ e o comunicador dos processos envolvidos na comunica¸ c˜ ao.

➤ status devolve informa¸ c˜ ao sobre o processo emissor (status.MPI SOURCE) e a marca da mensagem recebida (status.MPI TAG). Se essa informa¸c˜ ao for desprez´ avel indique MPI STATUS IGNORE.

13

(39)

Informa¸ c˜ ao Relativa ` a Recep¸ c˜ ao

MPI Get count(MPI Status *status, MPI Datatype datatype, int

*count)

➤ MPI Get count() devolve em count o n´ umero de elementos do tipo datatype

recebidos na mensagem associada com status.

(40)

Informa¸ c˜ ao Relativa ` a Recep¸ c˜ ao

MPI Get count(MPI Status *status, MPI Datatype datatype, int

*count)

➤ MPI Get count() devolve em count o n´ umero de elementos do tipo datatype recebidos na mensagem associada com status.

MPI Probe(int source, int tag, MPI Comm comm, MPI status *status)

➤ MPI Probe() sincroniza a recep¸ c˜ ao da pr´ oxima mensagem, retornando em status informa¸ c˜ ao sobre a mesma sem contudo proceder ` a sua recep¸ c˜ ao.

➤ A recep¸ c˜ ao dever´ a ser posteriormente feita com MPI Recv().

➤ E ´ ´ util em situa¸ c˜ oes em que n˜ ao ´ e poss´ıvel conhecer antecipadamente o tamanho da mensagem e assim evitar que esta exceda o buffer de recep¸ c˜ ao.

14

(41)

I’m Alive! (mpi alive.c)

#include "mpi.h"

#define STD_TAG 0

main(int argc, char **argv) { int i, my_rank, n_procs;

char msg[100];

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

MPI_Comm_size(MPI_COMM_WORLD, &n_procs);

if (my_rank != 0) {

sprintf(msg, "I’m alive!");

MPI_Send(msg, strlen(msg) + 1, MPI_CHAR, 0, STD_TAG, MPI_COMM_WORLD);

} else {

for (i = 1; i < n_procs; i++) {

MPI_Recv(msg, 100, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

printf("Proc %d: %s\n", status.MPI_SOURCE, msg);

} }

MPI_Finalize();

}

15

(42)

Modos de Comunica¸ c˜ ao

➤ Em MPI existem 4 modos de comunica¸ c˜ ao para envio de mensagens:

♦ Standard: MPI Send()

♦ Synchronous: MPI Ssend()

♦ Buffered: MPI Bsend()

♦ Ready: MPI Rsend()

(43)

Modos de Comunica¸ c˜ ao

➤ Em MPI existem 4 modos de comunica¸ c˜ ao para envio de mensagens:

♦ Standard: MPI Send()

♦ Synchronous: MPI Ssend()

♦ Buffered: MPI Bsend()

♦ Ready: MPI Rsend()

➤ Independentemente do modo de envio, a recep¸ c˜ ao ´ e sempre feita atrav´ es da

chamada MPI Recv().

(44)

Modos de Comunica¸ c˜ ao

➤ Em MPI existem 4 modos de comunica¸ c˜ ao para envio de mensagens:

♦ Standard: MPI Send()

♦ Synchronous: MPI Ssend()

♦ Buffered: MPI Bsend()

♦ Ready: MPI Rsend()

➤ Independentemente do modo de envio, a recep¸ c˜ ao ´ e sempre feita atrav´ es da chamada MPI Recv().

➤ Em qualquer um dos modos a ordem das mensagens ´ e sempre preservada:

(45)

Modos de Comunica¸ c˜ ao

➤ Em MPI existem 4 modos de comunica¸ c˜ ao para envio de mensagens:

♦ Standard: MPI Send()

♦ Synchronous: MPI Ssend()

♦ Buffered: MPI Bsend()

♦ Ready: MPI Rsend()

➤ Independentemente do modo de envio, a recep¸ c˜ ao ´ e sempre feita atrav´ es da chamada MPI Recv().

➤ Em qualquer um dos modos a ordem das mensagens ´ e sempre preservada:

♦ O processo A envia N mensagens para o processo B fazendo N chamadas a qualquer uma das fun¸ c˜ oes MPI Send().

♦ O processo B faz N chamadas a MPI Recv() para receber as N mensagens.

♦ O ambiente de execu¸ c˜ ao garante que a 1

a

chamada a MPI Send() ´ e empa- relhada com a 1

a

chamada a MPI Recv(), a 2

a

chamada a MPI Send() ´ e emparelhada com a 2

a

chamada a MPI Recv(), e assim sucessivamente.

16

(46)

Synchronous Send

MPI Ssend(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ S´ o quando o processo receptor confirmar que est´ a pronto a receber ´ e que o envio acontece. At´ e l´ a o processo emissor fica ` a espera.

Emissor

Receptor

tempo MPI_Recv

MPI_Ssend

➤ Este tipo de comunica¸ c˜ ao s´ o deve ser utilizado quando o processo emissor necessita de garantir a recep¸ c˜ ao antes de continuar a sua execu¸ c˜ ao.

➤ Este m´ etodo de comunica¸ c˜ ao pode ser ´ util para certas situa¸ c˜ oes. No entanto, ele pode atrasar bastante a aplica¸ c˜ ao, pois enquanto o processo receptor n˜ ao recebe a mensagem, o processo emissor poderia estar a executar trabalho ´ util.

17

(47)

Buffered Send

MPI Bsend(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ A mensagem ´ e copiada para um buffer local do programa e s´ o depois enviada. O processo emissor n˜ ao fica dependente da sincroniza¸ c˜ ao com o processo receptor, e pode desde logo continuar a sua execu¸ c˜ ao.

Emissor

Receptor

tempo MPI_Recv

MPI_Bsend

local buffer

➤ Tem a vantagem de n˜ ao requerer sincroniza¸ c˜ ao, mas o inconveniente de se ter de definir explicitamente um buffer associado ao programa.

18

(48)

Buffered Send

MPI Buffer attach(void *buf, int size)

➤ MPI Buffer attach() informa o ambiente de execu¸ c˜ ao do MPI que o espa¸co de

tamanho size bytes a partir do endere¸ co buf pode ser usado para buffering local

de mensagens.

(49)

Buffered Send

MPI Buffer attach(void *buf, int size)

➤ MPI Buffer attach() informa o ambiente de execu¸ c˜ ao do MPI que o espa¸co de tamanho size bytes a partir do endere¸ co buf pode ser usado para buffering local de mensagens.

MPI Buffer detach(void **buf, int *size)

➤ MPI Buffer detach() informa o ambiente de execu¸ c˜ ao do MPI que o actual buffer local de mensagens n˜ ao deve ser mais utilizado. Se existirem mensagens pendentes no buffer, a fun¸ c˜ ao s´ o retorna quando todas elas forem entregues.

➤ Em cada instante da execu¸ c˜ ao s´ o pode existir um ´ unico buffer associado a cada processo.

➤ A fun¸ c˜ ao MPI Buffer detach() n˜ ao liberta a mem´ oria associada ao buffer, para tal ´ e necess´ ario invocar explicitamente a fun¸ c˜ ao free() do sistema.

19

(50)

Welcome! (mpi welcome.c)

main(int argc, char **argv) { int buf_size; char *local_buf;

...

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

MPI_Comm_size(MPI_COMM_WORLD, &n_procs);

buf_size = BUF_SIZE; local_buf = (char *) malloc(buf_size);

MPI_Buffer_attach(local_buf, buf_size);

sprintf(msg, "Welcome!");

for (i = 0; i < n_procs; i++) if (my_rank != i)

MPI_Bsend(msg, strlen(msg) + 1, MPI_CHAR, i, STD_TAG, MPI_COMM_WORLD);

for (i = 0; i < n_procs; i++) if (my_rank != i) {

sprintf(msg, "Argh!");

MPI_Recv(msg, 100, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

printf("Proc %d->%d: %s\n", status.MPI_SOURCE, my_rank, msg);

}

MPI_Buffer_detach(&local_buf, &buf_size);

free(local_buf);

MPI_Finalize();

}

20

(51)

Standard Send

MPI Send(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ Termina assim que a mensagem ´ e enviada, o que n˜ ao significa que tenha sido entregue ao processo receptor. A mensagem pode ficar pendente no ambiente de execu¸ c˜ ao durante algum tempo (depende da implementa¸ c˜ ao do MPI).

Emissor

Receptor

tempo MPI_Recv

MPI_Send

MPI buffer

➤ Tipicamente, as implementa¸ c˜ oes fazem buffering de mensagens pequenas e sincronizam nas grandes. Para escrever c´ odigo port´ avel, o programador n˜ ao deve assumir que o envio termina antes nem depois de come¸ car a recep¸ c˜ ao.

21

(52)

Ready Send

MPI Rsend(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm)

➤ Esta forma de envio completa imediatamente. A comunica¸ c˜ ao sucede normal- mente se aparecer um receptor j´ a preparado para receber. Se n˜ ao existir um receptor, o resultado da comunica¸ c˜ ao ´ e indefinido. O programa deve estar logicamente correcto para que funcione.

Emissor

Receptor

tempo MPI_Rsend

MPI_Recv

➤ Esta forma de comunica¸ c˜ ao ´ e ´ util em casos muitos restritos, da´ı a maior parte dos programadores raramente a utilizarem.

22

(53)

Comunica¸ c˜ oes N˜ ao Bloqueantes

➤ Uma comunica¸c˜ ao diz-se bloqueante se a execu¸ c˜ ao ´ e interrompida enquanto

a comunica¸c˜ ao n˜ ao sucede. Uma comunica¸ c˜ ao bloqueante s´ o sucede quando o

buffer da mensagem associado ` a comunica¸ c˜ ao pode ser reutilizado.

(54)

Comunica¸ c˜ oes N˜ ao Bloqueantes

➤ Uma comunica¸c˜ ao diz-se bloqueante se a execu¸ c˜ ao ´ e interrompida enquanto a comunica¸c˜ ao n˜ ao sucede. Uma comunica¸ c˜ ao bloqueante s´ o sucede quando o buffer da mensagem associado ` a comunica¸ c˜ ao pode ser reutilizado.

➤ Uma comunica¸ c˜ ao diz-se n˜ ao bloqueante se a continua¸ c˜ ao da execu¸c˜ ao n˜ ao

depende do sucesso da comunica¸ c˜ ao. O buffer da mensagem associado a uma

comunica¸ c˜ ao n˜ ao bloqueante n˜ ao deve, no entanto, ser reutilizado pela aplica¸c˜ ao

at´ e que a comunica¸ c˜ ao suceda.

(55)

Comunica¸ c˜ oes N˜ ao Bloqueantes

➤ Uma comunica¸c˜ ao diz-se bloqueante se a execu¸ c˜ ao ´ e interrompida enquanto a comunica¸c˜ ao n˜ ao sucede. Uma comunica¸ c˜ ao bloqueante s´ o sucede quando o buffer da mensagem associado ` a comunica¸ c˜ ao pode ser reutilizado.

➤ Uma comunica¸ c˜ ao diz-se n˜ ao bloqueante se a continua¸ c˜ ao da execu¸c˜ ao n˜ ao depende do sucesso da comunica¸ c˜ ao. O buffer da mensagem associado a uma comunica¸ c˜ ao n˜ ao bloqueante n˜ ao deve, no entanto, ser reutilizado pela aplica¸c˜ ao at´ e que a comunica¸ c˜ ao suceda.

♦ A ideia das comunica¸ c˜ oes n˜ ao bloqueantes ´ e iniciar o envio das mensagens o

mais cedo poss´ıvel, continuar de imediato com a execu¸ c˜ ao, e verificar o mais

tarde poss´ıvel o sucesso das mesmas.

(56)

Comunica¸ c˜ oes N˜ ao Bloqueantes

➤ Uma comunica¸c˜ ao diz-se bloqueante se a execu¸ c˜ ao ´ e interrompida enquanto a comunica¸c˜ ao n˜ ao sucede. Uma comunica¸ c˜ ao bloqueante s´ o sucede quando o buffer da mensagem associado ` a comunica¸ c˜ ao pode ser reutilizado.

➤ Uma comunica¸ c˜ ao diz-se n˜ ao bloqueante se a continua¸ c˜ ao da execu¸c˜ ao n˜ ao depende do sucesso da comunica¸ c˜ ao. O buffer da mensagem associado a uma comunica¸ c˜ ao n˜ ao bloqueante n˜ ao deve, no entanto, ser reutilizado pela aplica¸c˜ ao at´ e que a comunica¸ c˜ ao suceda.

♦ A ideia das comunica¸ c˜ oes n˜ ao bloqueantes ´ e iniciar o envio das mensagens o mais cedo poss´ıvel, continuar de imediato com a execu¸ c˜ ao, e verificar o mais tarde poss´ıvel o sucesso das mesmas.

♦ Uma chamada a uma fun¸ c˜ ao n˜ ao bloqueante apenas anuncia ao ambiente

de execu¸ c˜ ao a existˆ encia de uma mensagem para ser enviada ou recebida. A

fun¸ c˜ ao completa de imediato.

(57)

Comunica¸ c˜ oes N˜ ao Bloqueantes

➤ Uma comunica¸c˜ ao diz-se bloqueante se a execu¸ c˜ ao ´ e interrompida enquanto a comunica¸c˜ ao n˜ ao sucede. Uma comunica¸ c˜ ao bloqueante s´ o sucede quando o buffer da mensagem associado ` a comunica¸ c˜ ao pode ser reutilizado.

➤ Uma comunica¸ c˜ ao diz-se n˜ ao bloqueante se a continua¸ c˜ ao da execu¸c˜ ao n˜ ao depende do sucesso da comunica¸ c˜ ao. O buffer da mensagem associado a uma comunica¸ c˜ ao n˜ ao bloqueante n˜ ao deve, no entanto, ser reutilizado pela aplica¸c˜ ao at´ e que a comunica¸ c˜ ao suceda.

♦ A ideia das comunica¸ c˜ oes n˜ ao bloqueantes ´ e iniciar o envio das mensagens o mais cedo poss´ıvel, continuar de imediato com a execu¸ c˜ ao, e verificar o mais tarde poss´ıvel o sucesso das mesmas.

♦ Uma chamada a uma fun¸ c˜ ao n˜ ao bloqueante apenas anuncia ao ambiente de execu¸ c˜ ao a existˆ encia de uma mensagem para ser enviada ou recebida. A fun¸ c˜ ao completa de imediato.

♦ A comunica¸ c˜ ao fica completa quando num momento posterior o processo toma conhecimento do sucesso da comunica¸ c˜ ao.

23

(58)

Envio N˜ ao Bloqueante de Mensagens

MPI Isend(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm, MPI Request *req)

MPI Issend(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm, MPI Request *req)

MPI Ibsend(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm, MPI Request *req)

MPI Irsend(void *buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm, MPI Request *req)

➤ Todas as fun¸ c˜ oes devolvem em req o identificador que permite a posterior verifica¸ c˜ ao do sucesso da comunica¸ c˜ ao.

24

(59)

Recep¸ c˜ ao N˜ ao Bloqueante de Mensagens

MPI Irecv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Request *req)

➤ MPI Irecv() devolve em req o identificador que permite a posterior verifica¸c˜ ao

do sucesso da comunica¸ c˜ ao.

(60)

Recep¸ c˜ ao N˜ ao Bloqueante de Mensagens

MPI Irecv(void *buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Request *req)

➤ MPI Irecv() devolve em req o identificador que permite a posterior verifica¸c˜ ao do sucesso da comunica¸ c˜ ao.

MPI Iprobe(int source, int tag, MPI Comm comm, int *flag, MPI status *status)

➤ MPI Iprobe() testa a chegada de uma mensagem associada com source, tag e comm sem contudo proceder ` a sua recep¸ c˜ ao. Retorna em flag o valor l´ ogico que indica a chegada de alguma mensagem, e em caso positivo retorna em status informa¸ c˜ ao sobre a mesma.

➤ A recep¸ c˜ ao dever´ a ser posteriormente feita com uma fun¸ c˜ ao de recep¸ c˜ ao.

25

(61)

Verificar o Sucesso duma Comunica¸ c˜ ao N˜ ao Bloqueante

MPI Wait(MPI Request *req, MPI Status *status)

➤ MPI Wait() bloqueia at´ e que a comunica¸ c˜ ao identificada por req suceda. Retorna

em status informa¸ c˜ ao relativa ` a mensagem.

(62)

Verificar o Sucesso duma Comunica¸ c˜ ao N˜ ao Bloqueante

MPI Wait(MPI Request *req, MPI Status *status)

➤ MPI Wait() bloqueia at´ e que a comunica¸ c˜ ao identificada por req suceda. Retorna em status informa¸ c˜ ao relativa ` a mensagem.

MPI Test(MPI Request *req, int *flag, MPI Status *status)

➤ MPI Test() testa se a comunica¸ c˜ ao identificada por req sucedeu. Retorna em flag o valor l´ ogico que indica o sucesso da comunica¸ c˜ ao, e em caso positivo retorna em status informa¸ c˜ ao relativa ` a mensagem.

26

(63)

Hello! (mpi hello.c)

main(int argc, char **argv) {

char recv_msg[100]; MPI_Request req[100];

...

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

MPI_Comm_size(MPI_COMM_WORLD, &n_procs);

sprintf(msg, "Hello!");

for (i = 0; i < n_procs; i++) if (my_rank != i) {

MPI_Irecv(recv_msg, 100, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &(req[i]));

MPI_Isend(msg, strlen(msg) + 1, MPI_CHAR, i, STD_TAG, MPI_COMM_WORLD, &(req[i + n_procs]));

}

for (i = 0; i < n_procs; i++) if (my_rank != i) {

sprintf(recv_msg, "Argh!");

MPI_Wait(&(req[i + n_procs]), &status);

MPI_Wait(&(req[i]), &status);

printf("Proc %d->%d: %s\n", status.MPI_SOURCE, my_rank, recv_msg);

}

MPI_Finalize();

}

27

(64)

Que Tipo de Mensagens Devo Utilizar?

(65)

Que Tipo de Mensagens Devo Utilizar?

➤ Grande parte dos utilizadores utiliza as vers˜ oes standard para envio e recep¸c˜ ao

de mensagens quando o ambiente de execu¸ c˜ ao possui implementa¸ c˜ oes eficien-

tes dessas fun¸c˜ oes. No entanto, o uso dessas fun¸ c˜ oes nem sempre garante a

portabilidade da aplica¸ c˜ ao.

(66)

Que Tipo de Mensagens Devo Utilizar?

➤ Grande parte dos utilizadores utiliza as vers˜ oes standard para envio e recep¸c˜ ao de mensagens quando o ambiente de execu¸ c˜ ao possui implementa¸ c˜ oes eficien- tes dessas fun¸c˜ oes. No entanto, o uso dessas fun¸ c˜ oes nem sempre garante a portabilidade da aplica¸ c˜ ao.

➤ Em alternativa, a utiliza¸ c˜ ao das vers˜ oes synchronous e standard n˜ ao bloqueante

´ e suficiente para construir aplica¸ c˜ oes robustas e ao mesmo tempo port´ aveis.

(67)

Que Tipo de Mensagens Devo Utilizar?

➤ Grande parte dos utilizadores utiliza as vers˜ oes standard para envio e recep¸c˜ ao de mensagens quando o ambiente de execu¸ c˜ ao possui implementa¸ c˜ oes eficien- tes dessas fun¸c˜ oes. No entanto, o uso dessas fun¸ c˜ oes nem sempre garante a portabilidade da aplica¸ c˜ ao.

➤ Em alternativa, a utiliza¸ c˜ ao das vers˜ oes synchronous e standard n˜ ao bloqueante

´ e suficiente para construir aplica¸ c˜ oes robustas e ao mesmo tempo port´ aveis.

➤ As vers˜ oes n˜ ao bloqueantes nem sempre levam a melhores resultados. A sua utili-

za¸ c˜ ao s´ o deve ser considerada quando existe uma clara e substancial sobreposi¸c˜ ao

da computa¸ c˜ ao.

(68)

Que Tipo de Mensagens Devo Utilizar?

➤ Grande parte dos utilizadores utiliza as vers˜ oes standard para envio e recep¸c˜ ao de mensagens quando o ambiente de execu¸ c˜ ao possui implementa¸ c˜ oes eficien- tes dessas fun¸c˜ oes. No entanto, o uso dessas fun¸ c˜ oes nem sempre garante a portabilidade da aplica¸ c˜ ao.

➤ Em alternativa, a utiliza¸ c˜ ao das vers˜ oes synchronous e standard n˜ ao bloqueante

´ e suficiente para construir aplica¸ c˜ oes robustas e ao mesmo tempo port´ aveis.

➤ As vers˜ oes n˜ ao bloqueantes nem sempre levam a melhores resultados. A sua utili- za¸ c˜ ao s´ o deve ser considerada quando existe uma clara e substancial sobreposi¸c˜ ao da computa¸ c˜ ao.

➤ E perfeitamente poss´ıvel enviar mensagens com fun¸ ´ c˜ oes n˜ ao bloqueantes e receber com fun¸ c˜ oes bloqueantes. O contr´ ario ´ e igualmente poss´ıvel.

28

(69)

Agrupar Dados para Comunica¸ c˜ ao

➤ Em programa¸c˜ ao com troca de mensagens, uma heur´ıstica natural para maximizar

a performance do sistema ´ e minimizar o n´ umero de mensagens a trocar.

(70)

Agrupar Dados para Comunica¸ c˜ ao

➤ Em programa¸c˜ ao com troca de mensagens, uma heur´ıstica natural para maximizar a performance do sistema ´ e minimizar o n´ umero de mensagens a trocar.

➤ Por defeito, todas as fun¸ c˜ oes de envio e recep¸ c˜ ao de mensagens permitem agrupar numa mesma mensagem dados do mesmo tipo guardados em posi¸c˜ oes cont´ıguas de mem´ oria.

datatype datatype ... datatype datatype

count

(71)

Agrupar Dados para Comunica¸ c˜ ao

➤ Em programa¸c˜ ao com troca de mensagens, uma heur´ıstica natural para maximizar a performance do sistema ´ e minimizar o n´ umero de mensagens a trocar.

➤ Por defeito, todas as fun¸ c˜ oes de envio e recep¸ c˜ ao de mensagens permitem agrupar numa mesma mensagem dados do mesmo tipo guardados em posi¸c˜ oes cont´ıguas de mem´ oria.

datatype datatype ... datatype datatype count

➤ Para al´ em desta funcionalidade b´ asica o MPI permite:

♦ Definir novos tipos de dados que agrupam dados de v´ arios tipos.

♦ Empacotar e desempacotar dados para/de um buffer.

29

(72)

Tipos Derivados

➤ A defini¸ c˜ ao de novos tipos de dados ´ e feita em tempo de execu¸ c˜ ao:

♦ Inicialmente, os processos devem construir o novo tipo derivado. A constru¸c˜ ao de tipos derivados ´ e feita a partir dos tipos de dados b´ asicos que o MPI define.

♦ Em seguida, devem certificar perante o ambiente de execu¸ c˜ ao do MPI a existˆ encia do novo tipo derivado.

♦ Ap´ os a sua utiliza¸ c˜ ao, cada processo liberta a certifica¸ c˜ ao feita.

(73)

Tipos Derivados

➤ A defini¸ c˜ ao de novos tipos de dados ´ e feita em tempo de execu¸ c˜ ao:

♦ Inicialmente, os processos devem construir o novo tipo derivado. A constru¸c˜ ao de tipos derivados ´ e feita a partir dos tipos de dados b´ asicos que o MPI define.

♦ Em seguida, devem certificar perante o ambiente de execu¸ c˜ ao do MPI a existˆ encia do novo tipo derivado.

♦ Ap´ os a sua utiliza¸ c˜ ao, cada processo liberta a certifica¸ c˜ ao feita.

➤ A constru¸ c˜ ao de tipos derivados ´ e dispendiosa, pelo que s´ o deve ser utilizada

quando o n´ umero de mensagens a trocar ´ e significativo.

(74)

Tipos Derivados

➤ A defini¸ c˜ ao de novos tipos de dados ´ e feita em tempo de execu¸ c˜ ao:

♦ Inicialmente, os processos devem construir o novo tipo derivado. A constru¸c˜ ao de tipos derivados ´ e feita a partir dos tipos de dados b´ asicos que o MPI define.

♦ Em seguida, devem certificar perante o ambiente de execu¸ c˜ ao do MPI a existˆ encia do novo tipo derivado.

♦ Ap´ os a sua utiliza¸ c˜ ao, cada processo liberta a certifica¸ c˜ ao feita.

➤ A constru¸ c˜ ao de tipos derivados ´ e dispendiosa, pelo que s´ o deve ser utilizada quando o n´ umero de mensagens a trocar ´ e significativo.

➤ Os novos tipos de dados s˜ ao utilizados nas fun¸ c˜ oes de envio e recep¸c˜ ao de mensagens tal como os restantes tipos b´ asicos. Para tal ´ e necess´ ario que ambos os processos emissor e receptor tenham certificado o novo tipo derivado.

Normalmente, isso ´ e feito na parte do c´ odigo que ´ e comum a ambos os processos.

30

(75)

Constru¸ c˜ ao de Tipos Derivados

MPI Type vector(int count, int blocklength, int stride, MPI Datatype oldtype, MPI Datatype *newtype)

➤ MPI Type vector() constr´ oi um novo tipo de dados a partir de um vector de

dados.

(76)

Constru¸ c˜ ao de Tipos Derivados

MPI Type vector(int count, int blocklength, int stride, MPI Datatype oldtype, MPI Datatype *newtype)

➤ MPI Type vector() constr´ oi um novo tipo de dados a partir de um vector de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado.

(77)

Constru¸ c˜ ao de Tipos Derivados

MPI Type vector(int count, int blocklength, int stride, MPI Datatype oldtype, MPI Datatype *newtype)

➤ MPI Type vector() constr´ oi um novo tipo de dados a partir de um vector de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado.

➤ blocklength ´ e o n´ umero de elementos cont´ıguos de cada bloco.

(78)

Constru¸ c˜ ao de Tipos Derivados

MPI Type vector(int count, int blocklength, int stride, MPI Datatype oldtype, MPI Datatype *newtype)

➤ MPI Type vector() constr´ oi um novo tipo de dados a partir de um vector de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado.

➤ blocklength ´ e o n´ umero de elementos cont´ıguos de cada bloco.

➤ stride ´ e o n´ umero de elementos cont´ıguos que separa o in´ıcio de cada bloco

(deslocamento).

(79)

Constru¸ c˜ ao de Tipos Derivados

MPI Type vector(int count, int blocklength, int stride, MPI Datatype oldtype, MPI Datatype *newtype)

➤ MPI Type vector() constr´ oi um novo tipo de dados a partir de um vector de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado.

➤ blocklength ´ e o n´ umero de elementos cont´ıguos de cada bloco.

➤ stride ´ e o n´ umero de elementos cont´ıguos que separa o in´ıcio de cada bloco (deslocamento).

➤ oldtype ´ e o tipo de dados dos elementos do vector.

(80)

Constru¸ c˜ ao de Tipos Derivados

MPI Type vector(int count, int blocklength, int stride, MPI Datatype oldtype, MPI Datatype *newtype)

➤ MPI Type vector() constr´ oi um novo tipo de dados a partir de um vector de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado.

➤ blocklength ´ e o n´ umero de elementos cont´ıguos de cada bloco.

➤ stride ´ e o n´ umero de elementos cont´ıguos que separa o in´ıcio de cada bloco (deslocamento).

➤ oldtype ´ e o tipo de dados dos elementos do vector.

➤ newtype ´ e o identificador do novo tipo derivado.

31

(81)

Constru¸ c˜ ao de Tipos Derivados

MPI Type vector(int count, int blocklength, int stride, MPI Datatype oldtype, MPI Datatype *newtype)

count = 2

blocklenght = 3

stride = 4 newtype

oldtype oldtype oldtype oldtype oldtype oldtype oldtype oldtype

32

(82)

Constru¸ c˜ ao de Tipos Derivados

MPI Type struct(int count, int blocklengths[], MPI Aint displacements[], MPI Datatype oldtypes[], MPI Datatype

*newtype)

➤ MPI Type struct() constr´ oi um novo tipo de dados a partir de uma estrutura

de dados.

(83)

Constru¸ c˜ ao de Tipos Derivados

MPI Type struct(int count, int blocklengths[], MPI Aint displacements[], MPI Datatype oldtypes[], MPI Datatype

*newtype)

➤ MPI Type struct() constr´ oi um novo tipo de dados a partir de uma estrutura de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado. Representa

igualmente o n´ umero de entradas nos vectores blocklengths[], displacements[] e

oldtypes[].

(84)

Constru¸ c˜ ao de Tipos Derivados

MPI Type struct(int count, int blocklengths[], MPI Aint displacements[], MPI Datatype oldtypes[], MPI Datatype

*newtype)

➤ MPI Type struct() constr´ oi um novo tipo de dados a partir de uma estrutura de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado. Representa igualmente o n´ umero de entradas nos vectores blocklengths[], displacements[] e oldtypes[].

➤ blocklengths[] ´ e o n´ umero de elementos cont´ıguos de cada bloco.

(85)

Constru¸ c˜ ao de Tipos Derivados

MPI Type struct(int count, int blocklengths[], MPI Aint displacements[], MPI Datatype oldtypes[], MPI Datatype

*newtype)

➤ MPI Type struct() constr´ oi um novo tipo de dados a partir de uma estrutura de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado. Representa igualmente o n´ umero de entradas nos vectores blocklengths[], displacements[] e oldtypes[].

➤ blocklengths[] ´ e o n´ umero de elementos cont´ıguos de cada bloco.

➤ displacements[] ´ e o deslocamento em bytes de cada bloco.

(86)

Constru¸ c˜ ao de Tipos Derivados

MPI Type struct(int count, int blocklengths[], MPI Aint displacements[], MPI Datatype oldtypes[], MPI Datatype

*newtype)

➤ MPI Type struct() constr´ oi um novo tipo de dados a partir de uma estrutura de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado. Representa igualmente o n´ umero de entradas nos vectores blocklengths[], displacements[] e oldtypes[].

➤ blocklengths[] ´ e o n´ umero de elementos cont´ıguos de cada bloco.

➤ displacements[] ´ e o deslocamento em bytes de cada bloco.

➤ oldtypes[] ´ e o tipo de dados dos elementos de cada bloco.

(87)

Constru¸ c˜ ao de Tipos Derivados

MPI Type struct(int count, int blocklengths[], MPI Aint displacements[], MPI Datatype oldtypes[], MPI Datatype

*newtype)

➤ MPI Type struct() constr´ oi um novo tipo de dados a partir de uma estrutura de dados.

➤ count ´ e o n´ umero de blocos de dados do novo tipo derivado. Representa igualmente o n´ umero de entradas nos vectores blocklengths[], displacements[] e oldtypes[].

➤ blocklengths[] ´ e o n´ umero de elementos cont´ıguos de cada bloco.

➤ displacements[] ´ e o deslocamento em bytes de cada bloco.

➤ oldtypes[] ´ e o tipo de dados dos elementos de cada bloco.

➤ newtype ´ e o identificador do novo tipo derivado.

33

(88)

Constru¸ c˜ ao de Tipos Derivados

MPI Type struct(int count, int blocklengths[], MPI Aint displacements[], MPI Datatype oldtypes[], MPI Datatype

*newtype)

count = 3

bloco 0 newtype

MPI_INT MPI_CHAR MPI_CHAR MPI_CHAR MPI_CHAR MPI_DOUBLE MPI_DOUBLE

bloco 1 bloco 2

blocklengths[3] = {1, 4, 2}

displacements[3] = {0, int_length, int_length + 4 * char_length}

oldtypes[3] = {MPI_INT, MPI_CHAR, MPI_DOUBLE}

34

(89)

Constru¸ c˜ ao de Tipos Derivados

➤ Um tipo derivado ´ e um objecto que especifica um conjunto de tipos b´ asicos e os respectivos deslocamentos. Os tipos b´ asicos indicam ao MPI como interpretar os bits, enquanto que os deslocamentos indicam onde se encontram esses bits.

➤ Para instanciar os deslocamentos dum novo tipo derivado deve utilizar-se uma das seguintes fun¸ c˜ oes:

MPI Type extent(MPI Datatype datatype, MPI Aint *extent)

➤ MPI Type extent() devolve em extent o tamanho em bytes do tipo de dados datatype.

MPI Address(void *location, MPI Aint *address)

➤ MPI Address() devolve em address o endere¸ co de mem´ oria de location.

35

(90)

Certificar e Libertar um Tipo Derivado

MPI Type commit(MPI Datatype *datatype)

➤ MPI Type commit() certifica perante o ambiente de execu¸ c˜ ao do MPI a

existˆ encia de um novo tipo derivado identificado por datatype.

(91)

Certificar e Libertar um Tipo Derivado

MPI Type commit(MPI Datatype *datatype)

➤ MPI Type commit() certifica perante o ambiente de execu¸ c˜ ao do MPI a existˆ encia de um novo tipo derivado identificado por datatype.

MPI Type free(MPI Datatype *datatype)

➤ MPI Type free() liberta do ambiente de execu¸ c˜ ao o tipo derivado identificado por datatype.

36

(92)

Extrair Colunas de Matrizes (mpi vector.c)

int my_matrix[ROWS][COLS];

int my_vector[ROWS];

MPI_Datatype col_matrix;

...

// construir um tipo derivado com ROWS blocos // de 1 elemento separados por COLS elementos

MPI_Type_vector(ROWS, 1, COLS, MPI_INT, &col_matrix);

MPI_Type_commit(&col_matrix);

(93)

Extrair Colunas de Matrizes (mpi vector.c)

int my_matrix[ROWS][COLS];

int my_vector[ROWS];

MPI_Datatype col_matrix;

...

// construir um tipo derivado com ROWS blocos // de 1 elemento separados por COLS elementos

MPI_Type_vector(ROWS, 1, COLS, MPI_INT, &col_matrix);

MPI_Type_commit(&col_matrix);

...

// enviar a coluna 1 de my_matrix

MPI_Send(&my_matrix[0][1], 1, col_matrix, dest, tag, comm);

...

// receber uma dada coluna na coluna 3 de my_matrix

MPI_Recv(&my_matrix[0][3], 1, col_matrix, source, tag, comm, &status);

...

// receber uma dada coluna em my_vector

MPI_Recv(&my_vector, ROWS, MPI_INT, source, tag, comm, &status);

(94)

Extrair Colunas de Matrizes (mpi vector.c)

int my_matrix[ROWS][COLS];

int my_vector[ROWS];

MPI_Datatype col_matrix;

...

// construir um tipo derivado com ROWS blocos // de 1 elemento separados por COLS elementos

MPI_Type_vector(ROWS, 1, COLS, MPI_INT, &col_matrix);

MPI_Type_commit(&col_matrix);

...

// enviar a coluna 1 de my_matrix

MPI_Send(&my_matrix[0][1], 1, col_matrix, dest, tag, comm);

...

// receber uma dada coluna na coluna 3 de my_matrix

MPI_Recv(&my_matrix[0][3], 1, col_matrix, source, tag, comm, &status);

...

// receber uma dada coluna em my_vector

MPI_Recv(&my_vector, ROWS, MPI_INT, source, tag, comm, &status);

...

// libertar o tipo derivado MPI_Type_free(&col_matrix);

37

(95)

Estruturas de Dados (mpi struct.c)

struct { int a; char b[4]; double c[2]; } my_struct;

...

int blocklengths[3];

MPI_Aint int_length, char_length, displacements[3];

MPI_Datatype oldtypes[3];

MPI_Datatype struct_type;

...

// construir o tipo derivado representando my_struct

blocklengths[0] = 1; blocklengths[1] = 4; blocklengths[2] = 2;

oldtypes[0] = MPI_INT; oldtypes[1] = MPI_CHAR; oldtypes[2] = MPI_DOUBLE;

MPI_Type_extent(MPI_INT, &int_length);

MPI_Type_extent(MPI_CHAR, &char_length);

displacements[0] = 0;

displacements[1] = int_length;

displacements[2] = int_length + 4 * char_length;

MPI_Type_struct(3, blocklengths, displacements, oldtypes, &struct_type);

MPI_Type_commit(&struct_type);

(96)

Estruturas de Dados (mpi struct.c)

struct { int a; char b[4]; double c[2]; } my_struct;

...

int blocklengths[3];

MPI_Aint int_length, char_length, displacements[3];

MPI_Datatype oldtypes[3];

MPI_Datatype struct_type;

...

// construir o tipo derivado representando my_struct

blocklengths[0] = 1; blocklengths[1] = 4; blocklengths[2] = 2;

oldtypes[0] = MPI_INT; oldtypes[1] = MPI_CHAR; oldtypes[2] = MPI_DOUBLE;

MPI_Type_extent(MPI_INT, &int_length);

MPI_Type_extent(MPI_CHAR, &char_length);

displacements[0] = 0;

displacements[1] = int_length;

displacements[2] = int_length + 4 * char_length;

MPI_Type_struct(3, blocklengths, displacements, oldtypes, &struct_type);

MPI_Type_commit(&struct_type);

...

// enviar my_struct

MPI_Send(&my_struct, 1, struct_type, dest, tag, comm);

...

// receber em my_struct

MPI_Recv(&my_struct, 1, struct_type, source, tag, comm, &status);

38

(97)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

➤ MPI Pack() permite empacotar dados n˜ ao cont´ıguos em posi¸ c˜ oes cont´ıguas de

mem´ oria.

(98)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

➤ MPI Pack() permite empacotar dados n˜ ao cont´ıguos em posi¸ c˜ oes cont´ıguas de mem´ oria.

➤ buf ´ e o endere¸ co inicial dos dados a empacotar.

(99)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

➤ MPI Pack() permite empacotar dados n˜ ao cont´ıguos em posi¸ c˜ oes cont´ıguas de mem´ oria.

➤ buf ´ e o endere¸ co inicial dos dados a empacotar.

➤ count ´ e o n´ umero de elementos do tipo datatype a empacotar.

(100)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

➤ MPI Pack() permite empacotar dados n˜ ao cont´ıguos em posi¸ c˜ oes cont´ıguas de mem´ oria.

➤ buf ´ e o endere¸ co inicial dos dados a empacotar.

➤ count ´ e o n´ umero de elementos do tipo datatype a empacotar.

➤ datatype ´ e o tipo de dados a empacotar.

(101)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

➤ MPI Pack() permite empacotar dados n˜ ao cont´ıguos em posi¸ c˜ oes cont´ıguas de mem´ oria.

➤ buf ´ e o endere¸ co inicial dos dados a empacotar.

➤ count ´ e o n´ umero de elementos do tipo datatype a empacotar.

➤ datatype ´ e o tipo de dados a empacotar.

➤ packbuf ´ e o endere¸ co do buffer onde devem ser colocados os dados a empacotar.

(102)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

➤ MPI Pack() permite empacotar dados n˜ ao cont´ıguos em posi¸ c˜ oes cont´ıguas de mem´ oria.

➤ buf ´ e o endere¸ co inicial dos dados a empacotar.

➤ count ´ e o n´ umero de elementos do tipo datatype a empacotar.

➤ datatype ´ e o tipo de dados a empacotar.

➤ packbuf ´ e o endere¸ co do buffer onde devem ser colocados os dados a empacotar.

➤ packsize ´ e o tamanho em bytes do buffer de empacotamento.

(103)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

➤ MPI Pack() permite empacotar dados n˜ ao cont´ıguos em posi¸ c˜ oes cont´ıguas de mem´ oria.

➤ buf ´ e o endere¸ co inicial dos dados a empacotar.

➤ count ´ e o n´ umero de elementos do tipo datatype a empacotar.

➤ datatype ´ e o tipo de dados a empacotar.

➤ packbuf ´ e o endere¸ co do buffer onde devem ser colocados os dados a empacotar.

➤ packsize ´ e o tamanho em bytes do buffer de empacotamento.

➤ position ´ e a posi¸ c˜ ao (em bytes ) do buffer a partir da qual os dados devem ser

empacotados.

(104)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

➤ MPI Pack() permite empacotar dados n˜ ao cont´ıguos em posi¸ c˜ oes cont´ıguas de mem´ oria.

➤ buf ´ e o endere¸ co inicial dos dados a empacotar.

➤ count ´ e o n´ umero de elementos do tipo datatype a empacotar.

➤ datatype ´ e o tipo de dados a empacotar.

➤ packbuf ´ e o endere¸ co do buffer onde devem ser colocados os dados a empacotar.

➤ packsize ´ e o tamanho em bytes do buffer de empacotamento.

➤ position ´ e a posi¸ c˜ ao (em bytes ) do buffer a partir da qual os dados devem ser empacotados.

➤ comm ´ e o comunicador dos processos envolvidos na comunica¸ c˜ ao.

39

(105)

Empacotar Dados

MPI Pack(void *buf, int count, MPI Datatype datatype, void

*packbuf, int packsize, int *position, MPI Comm comm)

count = 2

buf

datatype datatype

packbuf

packbuf

datatype packsize

datatype position

position MPI_Pack

40

(106)

Desempacotar Dados

MPI Unpack(void *packbuf, int packsize, int *position, void

*buf, int count, MPI Datatype datatype, MPI Comm comm)

➤ MPI Unpack() permite desempacotar dados cont´ıguos em posi¸ c˜ oes n˜ ao cont´ıguas

de mem´ oria.

(107)

Desempacotar Dados

MPI Unpack(void *packbuf, int packsize, int *position, void

*buf, int count, MPI Datatype datatype, MPI Comm comm)

➤ MPI Unpack() permite desempacotar dados cont´ıguos em posi¸ c˜ oes n˜ ao cont´ıguas de mem´ oria.

➤ packbuf ´ e o endere¸ co do buffer onde est˜ ao os dados a desempacotar.

(108)

Desempacotar Dados

MPI Unpack(void *packbuf, int packsize, int *position, void

*buf, int count, MPI Datatype datatype, MPI Comm comm)

➤ MPI Unpack() permite desempacotar dados cont´ıguos em posi¸ c˜ oes n˜ ao cont´ıguas de mem´ oria.

➤ packbuf ´ e o endere¸ co do buffer onde est˜ ao os dados a desempacotar.

➤ packsize ´ e o tamanho em bytes do buffer de empacotamento.

(109)

Desempacotar Dados

MPI Unpack(void *packbuf, int packsize, int *position, void

*buf, int count, MPI Datatype datatype, MPI Comm comm)

➤ MPI Unpack() permite desempacotar dados cont´ıguos em posi¸ c˜ oes n˜ ao cont´ıguas de mem´ oria.

➤ packbuf ´ e o endere¸ co do buffer onde est˜ ao os dados a desempacotar.

➤ packsize ´ e o tamanho em bytes do buffer de empacotamento.

➤ position ´ e a posi¸ c˜ ao (em bytes ) do buffer a partir da qual est˜ ao os dados a

desempacotar.

(110)

Desempacotar Dados

MPI Unpack(void *packbuf, int packsize, int *position, void

*buf, int count, MPI Datatype datatype, MPI Comm comm)

➤ MPI Unpack() permite desempacotar dados cont´ıguos em posi¸ c˜ oes n˜ ao cont´ıguas de mem´ oria.

➤ packbuf ´ e o endere¸ co do buffer onde est˜ ao os dados a desempacotar.

➤ packsize ´ e o tamanho em bytes do buffer de empacotamento.

➤ position ´ e a posi¸ c˜ ao (em bytes ) do buffer a partir da qual est˜ ao os dados a desempacotar.

➤ buf ´ e o endere¸ co inicial para onde os dados devem ser desempacotados.

(111)

Desempacotar Dados

MPI Unpack(void *packbuf, int packsize, int *position, void

*buf, int count, MPI Datatype datatype, MPI Comm comm)

➤ MPI Unpack() permite desempacotar dados cont´ıguos em posi¸ c˜ oes n˜ ao cont´ıguas de mem´ oria.

➤ packbuf ´ e o endere¸ co do buffer onde est˜ ao os dados a desempacotar.

➤ packsize ´ e o tamanho em bytes do buffer de empacotamento.

➤ position ´ e a posi¸ c˜ ao (em bytes ) do buffer a partir da qual est˜ ao os dados a desempacotar.

➤ buf ´ e o endere¸ co inicial para onde os dados devem ser desempacotados.

➤ count ´ e o n´ umero de elementos do tipo datatype a desempacotar.

(112)

Desempacotar Dados

MPI Unpack(void *packbuf, int packsize, int *position, void

*buf, int count, MPI Datatype datatype, MPI Comm comm)

➤ MPI Unpack() permite desempacotar dados cont´ıguos em posi¸ c˜ oes n˜ ao cont´ıguas de mem´ oria.

➤ packbuf ´ e o endere¸ co do buffer onde est˜ ao os dados a desempacotar.

➤ packsize ´ e o tamanho em bytes do buffer de empacotamento.

➤ position ´ e a posi¸ c˜ ao (em bytes ) do buffer a partir da qual est˜ ao os dados a desempacotar.

➤ buf ´ e o endere¸ co inicial para onde os dados devem ser desempacotados.

➤ count ´ e o n´ umero de elementos do tipo datatype a desempacotar.

➤ datatype ´ e o tipo de dados a desempacotar.

Imagem

Referências

temas relacionados :