Paradigmas de Computação Paralela Modelos e Linguagens de Computação Paralela João Luís Ferreira Sobral jls@... 1 Dezembro 2015
Razões para a computação paralela (cf. Skillicorn & Talia 1998) O mundo é intrinsecamente paralelo As linguagens atuais incentivam a expressão das ações sequencialmente Acesso a maior poder computacional O paralelismo permite o acesso a poder computacional que não está disponível numa máquina sequencial Limites físicos à computação sequencial Velocidade da luz, dissipação de calor, etc Maior eficiência em termos de custo de desenvolvimento dos sistemas Problemas da computação paralela Tradição de desenvolvimento de aplicações sequenciais A concepção de máquinas paralelas exige um balanço de múltiplos factores Os fabricantes de arquiteturas têm focado demasiado em HPC A portabilidade de desempenho entre arquiteturas paralelas é complexa Depende de características SW / HW
Conceitos básicos Arquitecturas SISD vs SIMD vs MIMD Memória partilhada vs memória distribuída Paralelismo lógico vs paralelismo físico Processo vs fios de execução Comunicação entre processos/fios Passagem de mensagens Memória partilhada Híbrido: acessos a memória remota Modelos de programação vs arquitectura do sistema
Facetas do desenvolvimento de aplicações paralelas Decomposição do programa em actividades paralelas Comunicação/sincronização entre actividades paralelas Mapeamento das actividades nos recursos disponíveis Problem Partitioning Identification of communication Task/communication agglomeration Modelos de computação paralela Nada explícito descrevem apenas o propósito do programa Paralelismo explícito o programador indica as oportunidades de paralelismo Paralelismo e decomposição explícita A comunicação/sincronização e mapeamento são implícitos Paralelismo, decomposição e mapeamento explícitos comunicação implícita Sincronização explícita Tudo explícito Mapping
Modelo de computação paralela nada é explícito Os Exploração de paralelismo pelos compiladores é reconhecidamente limitada Baseiam-se num programa sequencial Uma linguagem pode ser implicitamente executada em paralelo O sistema de suporte à linguagem encarrega-se da decomposição, etc É complexo garantir uma execução eficiente quando todos os aspectos da computação paralela são geridos implicitamente A gama de aplicações que se pode desenvolver é mais limitada que nas outras linguagens de mais baixo nível Exemplos típicos Linguagens declarativas (estrutura dinâmica)» High order functional programming: Haskell => redução de grafos facilmente paralelizada» Programação lógica: paralelismo AND e OR Esqueletos (programas com uma estrutura estática de componentes intrinsecamente paralelos)» P3L, M. Cole, JaSkel
Modelo de computação paralela nada é explícito Programação lógica (e.g., PROLOG) Paralelismo OR pesquisar cláusulas em paralelo a(x):- b(x). a(x):- c(x). Paralelismo AND pesquisar sub-objetivos em paralelo?- a(x), b(x), c(x) Esqueletos MAP - aplicar uma função a uma lista de elementos List<R> MAP(Func<T,R>, List<T>)
Paralelismo Explícito As atividades potencialmente paralelas são explícitas mas a decomposição em atividades paralelas, comunicação e mapeamento é automática. Em geral, o programador expressa um paralelismo de grão-fino que é posteriormente mapeado nos recursos disponíveis A implementação em sistemas de memória distribuída é, em geral, pouco eficiente, devido à complexidade do mapeamento. Data flow - A computação são operações com entradas e resultados explícitos, resultando num grafo de dependências Concurrent logic languages (PARLOG: Prolog anotado para especificar paralelismo) Lisp with futures (Multilisp) Parfor (sem expressar mais informação) HPF (Forall + data-distributions) Data parallel languages (e.g., NVIDIA CUDA, OpenCL)
Modelos e Linguagens de Computação Paralela Paralelismo Explícito Exemplo: GPU kernel (em APARAPI) para multiplicação de matrizes: public static void mmultgpu() { } "Kernel kernel = new Kernel() { " public void run() { int id = getglobalid(); for(int i=id/pesize; i<size; i+= pesize) { for(int j=id%pesize; j<size; j+= pesize) { float sum=0; " " for(int k=0; k<size; k++) } } } sum += A[i][k] * B[k][j]; C[i][j]=sum; }; kernel.execute( pesize*pesize); Simple Kernel (PE = matrix size) int i = getidy(); int j = getidx(); for(int k=0; k<size; k++) C[i][j] += A[i][k]*B[k][j]
Paralelismo e decomposição explícitos As atividades paralelas são explícitas mas o mapeamento e comunicação é implícito. Existem pouco exemplos desta classe BSP (Bulk Synchronous parallelism) Um programa constituído por um conjunto de atividades, divididas em passos de computação + comunicação» Os programas têm que ser explicitamente decompostos em atividades paralelas» A comunicação é implícita, na fase de comunicação e a sincronização é global» O mapeamento das atividades paralelas é também implícito Mapeamento explícito A decomposição em tarefas e atribuição das tarefas aos recursos é explícita, mas a comunicação é implícita Separação das primitivas de comunicação de computação Linda: espaço global de tuples partilhado (rd(xxx, val), wr(xxx,val) ) para comunicar entre atividades paralelas Sistemas baseados em memória partilhada distribuída (e.g., OpenMP c/dsm) RPC (Remote Procedure call)
Comunicação explícita Em geral baseado passagem de mensagens que reduzem a sincronização necessária (através de passagem assíncrona) Actores Objectos com uma fila de mensagens processada sequencialmente e que podem enviar mensagens a outros actores em reposta a uma mensagem Agregados concorrentes - Colecções de objectos referida por um só nome que podem processar mensagens de forma concorrente e fornecem capacidade de endereçamento intra-agregado Linguagens concorrentes orientadas ao objecto o paralelismo é encapsulado nos objectos Tudo explícito Todas as tarefas são da responsabilidade do programador Criação explícita de fios de execução/processos (Java, fork/join) Passagem de mensagens MPI_Send(buf,dest, ) + MPI_Recv(buf,src, ), MPI_Broadcast( ) CSP