Estratgias Pipelined Estratgias pipelined O problema dividido em
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 P 0 P 1 P 2 P 3 P 4 P 5
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 a[0] sum sin a sout a[1] sin a sout a[2] sin a sout a[3] sin a sout a[4] sin a sout
Filtrando um sinal Sinal sem a freqüência f 3 f 2 f 0 f 1 f(t) fin f 0 fout fin f 1 fout fin f 2 fout fin f 3 fout fin f 4 fout Sinal filtrado
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 m p-1 P 5 Instância Instância 3 4 1 2 5 P 4 Instância Instância 1 3 4 2 5 6 Instância Instância 3 4 7 1 2 5 6 P 3 P 2 P 1 P 0 Instância Instância Instância Instância 3 4 7 1 2 5 6 Instância Instância 3 4 1 2 5 7 6 Tempo
Diagrama espaço-tempo alternativo Instância 0 Instância 1 Instância 2 Instância 3 Instância 4 P 0 P 1 P 2 P 3 P 4 P 5 P 0 P 1 P 2 P 3 P 4 Tempo P 5
Diagrama espaço-tempo para tipo 2 Seqüência de dados: d 9 d 8 d 7 d 6 d 5 d 4 d 3 d 2 d 1 d 0 p-1 P 9 P 8 P 7 P 6 P 5 P 4 P 3 P 2 P 1 P 0 n d 0 d 1 d 2 d 3 d 0 d 1 d 2 d 3 d 4 d 5 d 6 d 7 d 0 d 1 d 2 d 3 d 4 d 5 d 6 d 7 d 8 d 9 Tempo d 1 d 2 d 3 d 4 d 5 d 6 d 7 d 8 d 9 d 5 d 6 d 7 d 8 d 9 d 9
Diagrama espaço-tempo para tipo 3 P 5 P 4 Transferência de informação suficiente para iniciar nova tarefa P 4 P 3 P 2 P 1 P 0 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 2 Processador 1 P 0 P 1 P 2 P 3 P 4 P 5 Processador 3 P 6 P 7 P 8
Plataforma computacional para aplicações pipelined Multiprocessador Computador host
Soma com pipeline P 0 P 1 P 2 P 3 P 4
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 P 0: send(&number, P 1); • Para o processador Pn-1: recv(&number, Pn-2); accumulation = accumulation + number;
Programa SPMD • Pseudo-código 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 Processo mestre dn-1. . . d 2 d 1 d 0 sum Escravos P 0 P 1 Pn-1
Adição de números com acesso direto aos processos escravos Processo mestre Números d 1 d 0 sum Escravos P 0 P 1 dn-1 Pn-1
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 P 0 1 2 3 4 5 6 7 8 9 10 P 1 P 2 P 3 P 4 4, 3, 1, 2, 5 4, 3, 1, 2 5 4, 3, 1 1 2 4, 3 5 3 21 4 5 2 4 3 5 1 1 3 4 5 2 4 5 32 1 5 5 4 4 3 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 P 0 Série de números xn-1. . . x 1 x 0 Menores números P 1 compara xmax Maior número Próximo maior número P 2
Ordenação utilizando configuração bidirecional Processo mestre dn-1. . . d 2 d 1 d 0 sum Escravos P 0 P 1 Pn-1
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); for (j = 0; j < right_procno; j++) { 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 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 P 0 P 1 P 2 Série de números xn-1. . . x 1 x 0 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 recv(&x, Pi-1); for (i = 0; i < n; i++) { recv(&number, Pi-1); 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 x 0 da última equação: • Esse valor é substituído na próxima equação para encontrar x 1 • E assim por diante:
Solução utilizando pipeline P 1 P 0 Calcula x 1 P 3 P 2 x 0 x 1 Calcula x 2 x 0 x 1 x 2 Calcula x 3 x 0 x 1 x 2 x 3
Solução utilizando pipeline • O processo i recebe os valores x 0, x 1, x 2, . . . , 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 P 5 P 4 P 3 P 2 P 1 P 0 Passou primeiro valor adiante Tempo Valor final calculado
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 2 i+1 tempos de comunicação e 2 i+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 2 n-1 passos de computação
- Slides: 39