Estratégias Pipelined
Estratégias pipelined O problema é dividido em uma série de tarefas que devem ser completadas uma após a outra Cada tarefa é executada por um processo separado ou processador P0 P1 P2 P3 P4 P5
Exemplo Somar todos os elementos de um array a em uma soma acumulativa for (i=0; i < n; i++) sum = sum + a[i]; O loop pode ser desdobrado em: sum = sum + a[0]; sum = sum + a[1]; sum = sum + a[2]; sum = sum + a[3]; sum = sum + a[4];
Pipeline para um loop desdobrado sum sin sout sin sout sin sout sin sout sin sout
Filtrando um sinal Sinal sem a freqüência f0 Sinal sem a freqüência f1 filtrado f0 f1 f2 f3 f4 f(t) fin fout fin fout fin fout fin fout fin fout
Utilização de pipeline Dado que um determinado problema pode ser dividido em uma série de tarefas seqüenciais, a estratégia de pipeline pode ser utilizada para aumentar a velocidade de processamento em três casos: 1.Se mais de uma instância do problema completo deve ser executada 2.Se uma série de dados deve ser processada e cada um dos dados requer múltiplas operações 3.Se a informação para iniciar a próxima tarefa pode ser passada a frente antes que o processo que a gera tenha completado todas as suas operações internas
Diagrama espaço-tempo para tipo 1 Instância 1 Instância 2 Instância 3 Instância 4 Instância 5 P4 Instância 1 Instância 2 Instância 3 Instância 4 Instância 5 Instância 6 P3 Instância 1 2 3 4 5 6 7 P2 Instância 1 Instância 2 Instância 3 Instância 4 Instância 5 Instância 6 Instância 7 P1 Instância 1 Instância 2 Instância 3 Instância 4 Instância 5 Instância 6 Instância 7 Instância 1 Instância 2 Instância 3 Instância 4 Instância 5 Instância 6 Instância 7 P0 Tempo
Diagrama espaço-tempo alternativo Instância 0 P0 P1 P2 P3 P4 P5 Instância 1 P0 P1 P2 P3 P4 P5 Instância 2 P0 P1 P2 P3 P4 P5 Instância 3 P0 P1 P2 P3 P4 P5 Instância 4 Tempo
Diagrama espaço-tempo para tipo 2 Seqüência de dados: d9d8d7d6d5d4d3d2d1d0 p-1 n P9 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P8 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P7 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P6 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P5 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P4 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P3 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P2 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P1 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 P0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 Tempo
Diagrama espaço-tempo para tipo 3 Transferência de informação suficiente para iniciar nova tarefa P3 P3 P2 P2 P1 P1 P0 P0 Tempo Tempo
Particionando processos entre processadores Se o número de estágios é maio que o número de processadores, um grupo de estágios pode ser designado para cada um dos processadores Processador 1 Processador 2 Processador 3 P0 P1 P2 P3 P4 P5 P6 P7 P8
Plataforma computacional para aplicações pipelined Multiprocessador Computador host
Soma com pipeline P0 P1 P2 P3 P4
Pseudo-código O código básico para o processador Pi: recv(&accumulation, Pi-1); accumulation = accumulation + number; send(&accumulation, Pi+1); Para o processador P0: send(&number, P1); Para o processador Pn-1: recv(&number, Pn-2);
Programa SPMD Pseudo-código O resultado final está no último processo If (proces > 0) { recv(&accumulation, Pi-1); accumulation = accumulation + number; } if (process < n-1) send(&accumulation, Pi+1); O resultado final está no último processo Outras operações aritméticas podem ser executadas
Adição de números com processo mestre e configuração em anel Escravos dn-1...d2d1d0 P0 P1 Pn-1 sum
Adição de números com acesso direto aos processos escravos Processo mestre Números Escravos dn-1 d0 d1 P0 P1 Pn-1 sum
Análise de complexidade O primeiro exemplo é do tipo 1 e cada processo executa ações similares em cada ciclo de pipeline Tempo total de execução:
Análise de complexidade Para uma instância Para múltiplas instâncias: um ciclo de pipeline
Particionamento de dados com múltiplas instâncias do problema Aumentando a partição de dados d, o impacto na comunicação diminui, mas diminui o paralelismo e aumenta o tempo de execução
Ordenação por inserção 4,3,1,2,5 1 2 4,3,1,2 5 2 3 4,3,1 5 1 4 4,3 5 2 3 1 5 4 5 2 4 2 6 5 3 1 3 1 7 5 4 2 2 8 5 4 3 1 1 9 5 4 3 2 10 5 4 3 2 1
Pseudo-código O algoritmo básico para o processo Pi é: recv(&number, Pi-1); if (number > x) { send (&x, Pi+1); x = number; } else send (&number, Pi+1); Com n números, o processo i aceita n-1 números e passa a frente n-i-1 números.
Pipeline para inserção Menores números P1 P2 Série de números xn-1...x1x0 compara xmax Próximo maior número Maior número
Ordenação utilizando configuração bidirecional Processo mestre Escravos dn-1...d2d1d0 P0 P1 Pn-1 sum
Pseudo-código right_procno=n-i-1; recv(&x, Pi-1); for (j = 0; j < right_procno; j++) { recv(&number, Pi-1); if (number > x) { send (&x, Pi+1); x = number; } else send (&number, Pi+1); send (&x, Pi-1); recv(&number, Pi+1); send (&number, Pi-1);
Análise de complexidade
Geração de números primos - Método de Eratóstenes Para encontrar os números primos entre 2 e n, gera-se a série de todos os números até n O número 2 é o primeiro número primo e todos os múltiplos de 2 são removidos da lista, pois não podem ser primos Considera-se o próximo número da lista e removem-se seus múltiplos até chegar a n Somente se analisam os números até , porque os números maiores que já foram examinados
Código seqüencial Análise de complexidade for (i =2; i < n; i++) prime[i] = 1; for (i =2; i < =sqrt_n; i++) if (prime[i] == 1) for (j = i + 1; j < n; j = j + i) prime[j] = 0; Análise de complexidade Existem múltiplos de 2, múltiplos de 3
Análise de complexidade Existem múltiplos de 2, múltiplos de 3
Pipeline para geração de números primos Números não múltiplos do primeiro número primo P0 P1 P2 Série de números xn-1...x1x0 Compara múltiplos Primeiro número primo Segundo número primo Terceiro número primo
Pseudo-código Para cada processador Pi: recv(&x, Pi-1); recv(&number, Pi-1); if ((number %x) != 0 ) send (&number, Pi+1); Como a quantidade de números não é a mesma e é desconhecida para cada processador, utiliza-se uma mensagem de finalização for (i = 0; i < n; i++) { if (number == terminator) break; if (number % x ) != 0) send (&number, Pi+1); }
Resolvendo um sistema de equações lineares Exemplo do tipo 3, os processos podem continuar depois de passar informação Exemplo: resolver sistema de equações lineares da forma triangular superior:
Resolução por substituição Encontra-se primeiro x0 da última equação: Esse valor é substituído na próxima equação para encontrar x1 E assim por diante:
Solução utilizando pipeline x0 x0 x0 Calcula x0 x0 Calcula x1 Calcula x2 Calcula x3 x1 x1 x1 x2 x2 x3
Solução utilizando pipeline O processo i recebe os valores x0,x1,x2,...,xi-1 e calcula xi através da equação:
Código seqüencial x[0] = b[0]/a[0][0]; for (i = 1; i < n; i++) { sum = 0; for (j = 0; j < i; j++) sum = sum + a[i][j]*x[j]; x[i] = (b[i] - sum)/a[i][i]; }
Código paralelo for (j = 0; i< j; j++) { recv(&x[j], Pi-1); send (&x[j], Pi+1); } sum = 0; for (j = 0; j < i; j++) sum = sum + a[i][j]*x[j]; x[i] = (b[i] - sum)/a[i][i]; send (&x[i], Pi+1);
Diagrama espaço-tempo para processo pipeline para resolução de sistemas lineares Valor final calculado P3 P2 P1 Passou primeiro valor adiante P0 Tempo
Análise de complexidade Não pode assumir que o esforço computacional será o mesmo em todos os estágios do pipeline O primeiro processo executa uma divisão e um envio de mensagem O processo i executa i envios e i recebimentos de mensagens, i multiplicações/adições, uma divisão/subtração e um envio final, em um total de 2i+1 tempos de comunicação e 2i+2 passos de computação O último processo executa n-1 recebimentos, n-1 multiplicações/somas e uma divisão/subtração, totalizando n-1 tempos de comunicação e 2n-1 passos de computação