Ajude a manter o site livre, gratuito e sem propagandas. Colabore!
Em computação distribuída, rotinas de comunicação entre as instâncias de processamento são utilizadas para o compartilhamento de dados. Comunicações ponto-a-ponto são aquelas que envolvem apenas duas instâncias de processamento.
O envio e recebimento de dados entre duas instâncias de processamento pode ser feita com as rotinas MPI_Send e MPI_Recv. A primeira é utilizada para o envio de um dado a partir de uma instância de processamento e a segunda é utilizada para o recebimento de um dado em uma outra instância de processamento.
A sintaxe da MPI_Send é
e a sintaxe da MPI_Recv é
O primeiro argumento é o ponteiro do buffer de dados. No caso do MPI_Send é o ponteiro para a posição da memória do dado a ser enviado. No caso do MPI_Recv é o ponteiro para a posição da memória do dado a ser recebido. O segundo argumento count é o número de dados sequenciais a serem enviados. O argumento datatype é o tipo de dado. O Open MPI suporta os seguintes tipos de dados
Ainda sobre as sintaxes acima, o argumento source é o identificador rank da instância de processamento. O argumento tag é um número arbitrário para identificar a operação de envio e recebimento. O argumento Comm especifica o comunicador (MPI_COMM_WORLD+ para aplicações básicas) e o último (somente para o MPI_Recv) fornece informação sobre o status do recebimento do dado.
Vamos estudar o seguinte código abaixo.
O código acima pode ser rodado com pelo menos duas instâncias de processamento. Nas linhas 20-21, o processo 0 envia o número 3.1416
(alocado na variável x
) para o processo 1. Nas linhas 24-25, o processo 1 recebe o número enviado pelo processo 0 e o aloca na variável y
.
As rotinas MPI_Send e MPI_Recv provocam a sincronização entre os processos envolvidos. Por exemplo, no código acima, no que o processo 0 atinge a rotina MPI_Send ele ficará aguardando o processo 1 receber todos os dados enviados e só, então, irá seguir adiante no código. Analogamente, no que o processo 1 atingir a rotina MPI_Recv, ele ficará aguardando o processo 0 enviar todos os dados e só, então, irá seguir adiante no código.
As rotinas MPI_Send e MPI_Recv podem ser utilizadas para o envio e recebimento de arrays. A sintaxe é a mesma vista acima, sendo que o primeiro argumento *buf deve apontar para o início da array e o segundo argumento count corresponde ao tamanho da array.
Estudemos o seguinte código. Nele, o processo 0 aloca e o processo 1 aloca . O processo 0 envia os valores para o processo 1. Então, o processo 1 recebe estes valores e os aloca em . Desta forma, a saída impressa no terminal é
(3.1) |
Verifique!
O Open MPI também suporta rotinas MPI_Isend de envio e MPI_Irecv de recebimento assíncronos. Neste caso, o processo emissor envia o dado para outro processo e segue imediatamente a computação. O processo receptor deve conter uma rotina MPI_Irecv, mas também não aguarda sua conclusão para seguir a computação.
O último argumento permite verificar os envios e recebimentos.
Estudemos o seguinte código.
Neste código, MPI_Status e MPI_Request são alocados nas linhas 2 e 3, respectivamente. O Processo 0 faz uma requisição de envio do número para o processo 1, não aguarda o recebimento e segue adiante. O processo 1 tem uma rotina de requisição de recebimento não assíncrona na linha 14. Neste momento, ele não necessariamente recebe o dado enviado pelo processador (isto pode ocorrer a qualquer momento mais adiante). Na linha 17, o valor de y pode ainda ser 0.0. Consulte a saída do código!
Podemos verificar se uma requisição de envio (ou recebimento) foi completa usando a rotina MPI_Test. A sua sintaxe é:
O flag == 0 caso a requisição ainda não tenha sido completada e flag == 1 caso a requisição tenha sido executada.
No Código 9 acima, as linhas de código 20-22 são utilizadas para fazê-lo aguardar até que a requisição de recebimento seja completada. Desta forma, na linha 24 o valor de y é (o valor enviado pelo processo 0). Verifique!
Faça um código C++/Open MPI para computar a média
(3.2) |
onde é um número em ponto flutuante e . Para a comunicação entre os processos, utilize apenas as rotinas MPI_Send e MPI_Recv.
Fala para o caso de divisível pelo número de processos.
Fala para o caso de não divisível pelo número de processos.
Faça um código C++/Open MPI para computação do produto interno entre dois vetores
(3.3) | |||
(3.4) |
Para a comunicação entre os processos, utilize apenas as rotinas MPI_Send e MPI_Recv. O processo 0 deve receber os resultados parciais dos demais processos e escrever na tela o valor computado do produto interno.
Faça para o caso de divisível pelo número de processos.
Faça para o caso de não divisível pelo número de processos.
Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!
Este texto é disponibilizado nos termos da Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional. Ícones e elementos gráficos podem estar sujeitos a condições adicionais.
Ajude a manter o site livre, gratuito e sem propagandas. Colabore!
Em computação distribuída, rotinas de comunicação entre as instâncias de processamento são utilizadas para o compartilhamento de dados. Comunicações ponto-a-ponto são aquelas que envolvem apenas duas instâncias de processamento.
O envio e recebimento de dados entre duas instâncias de processamento pode ser feita com as rotinas MPI_Send e MPI_Recv. A primeira é utilizada para o envio de um dado a partir de uma instância de processamento e a segunda é utilizada para o recebimento de um dado em uma outra instância de processamento.
A sintaxe da MPI_Send é
e a sintaxe da MPI_Recv é
O primeiro argumento é o ponteiro do buffer de dados. No caso do MPI_Send é o ponteiro para a posição da memória do dado a ser enviado. No caso do MPI_Recv é o ponteiro para a posição da memória do dado a ser recebido. O segundo argumento count é o número de dados sequenciais a serem enviados. O argumento datatype é o tipo de dado. O Open MPI suporta os seguintes tipos de dados
Ainda sobre as sintaxes acima, o argumento source é o identificador rank da instância de processamento. O argumento tag é um número arbitrário para identificar a operação de envio e recebimento. O argumento Comm especifica o comunicador (MPI_COMM_WORLD+ para aplicações básicas) e o último (somente para o MPI_Recv) fornece informação sobre o status do recebimento do dado.
Vamos estudar o seguinte código abaixo.
O código acima pode ser rodado com pelo menos duas instâncias de processamento. Nas linhas 20-21, o processo 0 envia o número 3.1416
(alocado na variável x
) para o processo 1. Nas linhas 24-25, o processo 1 recebe o número enviado pelo processo 0 e o aloca na variável y
.
As rotinas MPI_Send e MPI_Recv provocam a sincronização entre os processos envolvidos. Por exemplo, no código acima, no que o processo 0 atinge a rotina MPI_Send ele ficará aguardando o processo 1 receber todos os dados enviados e só, então, irá seguir adiante no código. Analogamente, no que o processo 1 atingir a rotina MPI_Recv, ele ficará aguardando o processo 0 enviar todos os dados e só, então, irá seguir adiante no código.
As rotinas MPI_Send e MPI_Recv podem ser utilizadas para o envio e recebimento de arrays. A sintaxe é a mesma vista acima, sendo que o primeiro argumento *buf deve apontar para o início da array e o segundo argumento count corresponde ao tamanho da array.
Estudemos o seguinte código. Nele, o processo 0 aloca e o processo 1 aloca . O processo 0 envia os valores para o processo 1. Então, o processo 1 recebe estes valores e os aloca em . Desta forma, a saída impressa no terminal é
(3.1) |
Verifique!
O Open MPI também suporta rotinas MPI_Isend de envio e MPI_Irecv de recebimento assíncronos. Neste caso, o processo emissor envia o dado para outro processo e segue imediatamente a computação. O processo receptor deve conter uma rotina MPI_Irecv, mas também não aguarda sua conclusão para seguir a computação.
O último argumento permite verificar os envios e recebimentos.
Estudemos o seguinte código.
Neste código, MPI_Status e MPI_Request são alocados nas linhas 2 e 3, respectivamente. O Processo 0 faz uma requisição de envio do número para o processo 1, não aguarda o recebimento e segue adiante. O processo 1 tem uma rotina de requisição de recebimento não assíncrona na linha 14. Neste momento, ele não necessariamente recebe o dado enviado pelo processador (isto pode ocorrer a qualquer momento mais adiante). Na linha 17, o valor de y pode ainda ser 0.0. Consulte a saída do código!
Podemos verificar se uma requisição de envio (ou recebimento) foi completa usando a rotina MPI_Test. A sua sintaxe é:
O flag == 0 caso a requisição ainda não tenha sido completada e flag == 1 caso a requisição tenha sido executada.
No Código 9 acima, as linhas de código 20-22 são utilizadas para fazê-lo aguardar até que a requisição de recebimento seja completada. Desta forma, na linha 24 o valor de y é (o valor enviado pelo processo 0). Verifique!
Faça um código C++/Open MPI para computar a média
(3.2) |
onde é um número em ponto flutuante e . Para a comunicação entre os processos, utilize apenas as rotinas MPI_Send e MPI_Recv.
Fala para o caso de divisível pelo número de processos.
Fala para o caso de não divisível pelo número de processos.
Faça um código C++/Open MPI para computação do produto interno entre dois vetores
(3.3) | |||
(3.4) |
Para a comunicação entre os processos, utilize apenas as rotinas MPI_Send e MPI_Recv. O processo 0 deve receber os resultados parciais dos demais processos e escrever na tela o valor computado do produto interno.
Faça para o caso de divisível pelo número de processos.
Faça para o caso de não divisível pelo número de processos.
Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!
Este texto é disponibilizado nos termos da Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional. Ícones e elementos gráficos podem estar sujeitos a condições adicionais.