Os modelos de programação paralela...



Documentos relacionados
Sistemas Operacionais II

Sistemas Operacionais I

COMPUTAÇÃO PARALELA. uma visão geral. Guilherme Galante. v.2.0

OO Engenharia Eletrônica

Programação em Paralelo. N. Cardoso & P. Bicudo. Física Computacional - MEFT 2010/2011

Mochila Binária com OpenMP

Programação em Paralelo. N. Cardoso & P. Bicudo. Física Computacional - MEFT 2010/2011

Sistemas Operacionais

Capítulo 8 Arquitetura de Computadores Paralelos

Programação com Posix Threads

Processos e Threads (partes I e II)

HPF & UPC. Modelos de programação PGAS. Paulo Matias. Seminários de Arquiteturas Avançadas de Computadores, Universidade de São Paulo

Infra-Estrutura de Software. Introdução. (cont.)

Um processo sob UNIX ocupa uma área de memória formada basicamente por 3 partes:

Capítulo 2. Charm++ 16

1.6. Tratamento de Exceções

Threads em Ambiente LINUX. Estudo e testes com a biblioteca pthreads

Arquitetura NUMA 1. Daniel de Angelis Cordeiro. INRIA MOAIS project Laboratoire d Informatique de Grenoble Université de Grenoble, França

Linguagem de Programação JAVA. Técnico em Informática Professora Michelle Nery

Arquitecturas Paralelas I Computação Paralela em Larga Escala. Passagem de Mensagens

Sistemas Operacionais

Sistemas Operacionais

LCAD. ALGORÍTMOS PARALELOS (Aula 6) Neyval C. Reis Jr. OUTUBRO/2004. Laboratório de Computação de Alto Desempenho DI/UFES.

Programação de Computadores - I. Profª Beatriz Profº Israel

Programação Paralela e Distribuída (DCC/UFRJ)

Alocação Dinâmica e Transparente de Computadores Ociosos em Java

INF 1620 P1-10/04/02 Questão 1 Nome:

Introdução. O que vimos. Infraestrutura de Software. (cont.) História dos Sistemas Operacionais. O que vimos 12/03/2012. Primeira geração:

Programação Paralela e Concorrente

Unidade IV: Ponteiros, Referências e Arrays

ÁREA DE CONCENTRAÇÃO EM SISTEMAS E CONTROLE - PG-EEC/S

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

Programação em Memória Compartilhada com OpenMP

Concorrência e Paralelismo

Programação Estruturada I

Ferramentas para Programação em Processadores Multi-Core

Java. Marcio de Carvalho Victorino

slide 0 Algoritmos Paralelos

Programação Sistemas

ESTUDO DE CASO WINDOWS VISTA

Sistemas Distribuídos RPC x RMI. Edeyson Andrade Gomes

Programação Concorrente

Tipo de Dados em Linguagem C

Tipos de Dados, Tipos Abstratos de Dados Estruturas de Dados

Linguagem de Programação III

Oracle Grid Engine. Thiago Marques Soares. Pós-Graduação em Modelagem Computacional Universidade Federal de Juiz de Fora. 8 de abril de 2015

Sistemas Operacionais. Patrícia Megumi Matsumoto Luciana Maria Gregolin Dias

Sua resposta deve conter entre 50 a 100 palavras, incluindo o exemplo.

ALGORÍTMOS PARALELOS (Aula 2) LCAD. Neyval C. Reis Jr. OUTUBRO/2004. Laboratório de Computação de Alto Desempenho DI/UFES

Ntrip Detalhes de Implementação do Protocolo

Grupo I [6v] Considere o seguinte extracto de um programa de definição de uma calculadora apenas com a função soma de dois valores reais

Resumo até aqui. Gerenciamento Proteção Compartilhamento. Infra-estrutura de Software

SIMULADOR DE ROTEAMENTO DE PACOTES (V. 3 20/05/2010)

Desenvolvimento OO com Java Orientação a objetos básica

POSIX Threads. Walter Fetter Lages.

Simulação de um catálogo espectrofotométrico III ABC do método de Monte Carlo. Laerte Sodré Jr. Fevereiro, 2011

Na Aula Anterior... O Conceito de Threads

apt-get install openssh-client (Debian) yum install openssh-clents (Fedora) slapt-get install openssh (Slackware)

Paralelização de Simuladores de Hardware Descritos em SystemC

Trabalhando com Processos e Threads em Ambiente LINUX

UNIVERSIDADE FEDERAL DO RIO GRANDE DO SUL INSTITUTO DE INFORMÁTICA INFORMÁTICA APLICADA

PROCESSOS. Prof. Maicon A. Sartin

Universidade da Beira Interior Cursos: Matemática /Informática e Ensino da Informática

Orientação a Objetos com Java

Conceitos de Linguagens de Programação

Definindo melhor alguns conceitos

FBV - Linguagem de Programação II. Um pouco sobre Java

Threads Aula 04 2 Quadrimestre

Exercício 1. Tabela 1: Cadastro de usuários, senhas e privilégios (exemplo). Login Senha Privilégio Armamento

ALGORÍTMOS PARALELOS LCAD. Neyval C. Reis Jr. OUTUBRO/2004. Laboratório de Computação de Alto Desempenho DI/UFES

Parte da Tarefa. Parte da Tarefa. Parte da Tarefa SEND RECEIVE SEND RECEIVE

Multi-processamento. Arquitecturas MIMD de memória partilhada Multi-cores heterogéneos Multi-processadores

Estudo Qualitativo e Quantitativo de Linguagens Paralelas para Arquiteturas Multicore

Linguagem de Programação I

GABARITO COMENTADO SISTEMAS OPERACIONAIS. PROF. Cláudio de C. Monteiro, Evanderson S. de Almeida, Vinícius de M. Rios

2 Orientação a objetos na prática

Resumo da última aula. Compiladores. Tipos. Regras semânticas. Expressões de tipos. Análise Semântica e checagem de tipos.

Programação Paralela com Troca de Mensagens. Profa Andréa Schwertner Charão DLSC/CT/UFSM

Básico, Ferramentas e o Primeiro Programa em Qt

É a associação de mais de um fluxo de execução em um único processo.

1. Discute as vantagens e desvantagens dum sistema de memória paginada, indicando também a importância do sistema dispôr duma memória cache.

Programação Estruturada. Programação Estruturada. Idéias Básicas da Programação Estruturada

MÓDULO 02 PROCESSOS E THREADS PROCESSOS e THREADS

Avaliação do Uso de Xen em Ambientes de Computação de Alto Desempenho

Sistemas Operacionais Aula 06: Threads. Ezequiel R. Zorzal

Controle de granularidade de tarefas em OpenMP

Pthreads. O que são threads? Mario João Junior. Uma thread é um fluxo de execução de instruções que pode ser escalonado pelo sistema operacional.

Bruno Hott Algoritmos e Estruturas de Dados I DECSI UFOP. Alocação Dinâmica de Memória

Slides_Java_1 !"$ % & $ ' ' Output: Run java. Compile javac. Name of program. Must be the same as name of file. Java source code.

Introdução a Computação

Programação Engenharia Informática (11543) 1º ano, 1º semestre Tecnologias e Sistemas de Informação (6619) 1º ano, 1º semestre

Membros de classe e de instância. PARTE III: Java e OO - detalhes. Exemplo 1: método. Exercício. Exemplo 1 corrigido

Orientação a Objetos

Exercício de Revisão Linguagem C

Transcrição:

Programação Paralela e Hierarquia de Memória Nicolas Maillard Roteiro Qual é o problema? Soluções tradicionais para programação paralela MPI Posix Threads OpenMP Soluções emergentes UPC Fortress, Chapel, Titanium, etc... O problema COMO DESCREVER o PARALELISMO num programa? 1

O que se quer de um modelo de programação? Um modelo de programação paralela Precisa ser expressivo: em geral, complexo. Abrange muitos parâmetros. deve levar a uma implementação do algoritmo. Precisa abstrair os fenômenos para capturar as caraterísticas gerais i.e. ser genérico! Precisa possibilitar desempenho bom. i.e. poder levar em consideração a arquitetura. Qual modelo de hardware? Os modelos de programação paralela... Não existe um modelo universal para programação paralela! Existem vários modelos para vários tipos de máquinas e vários tipos de programas; processos leves memória compartilhada. SMPs, CPUS multicores... Processos comunicantes troca de mensagem Memória distribuída Paralelismo de dados Owner Compute Rule Single Program Multiple Data Paralelismo de laços Influência de trabalhos em Compiladores Dificuldade para extração automática do paralelismo Paralelismo funcional / Divisão e Conquista paralela Templates para programação paralela Os resultados mais importantes foram obtidos até agora com modelos de memória compartilhada. Limitados em escalabilidade! Modelos de máquina Desconsiderar as comunicações (PRAM) Funciona para máquinas com memória compartilhada Funciona para processadores Multicore. Considerar uma máquina estática e homogênea, com rede perfeita (e.g. latência = 0) Considerar uma máquina estática homogênea, com rede que sofre de latência/vazão/contenção (LogP) Funciona para um cluster Considerar uma máquina dinâmica (Grid)... Ninguém sabe fazer. 2

Modelo de programa vs. Modelo de máquina RMI/RPC Java Processos comunicantes Threads Modelo de programa OpenMP Posix Threads Cilk PVM/MPI Satin Modelo de máquina Mem. compartilhada Mem. distribuída Message-Passing Interface (Não perder muito tempo!) Posix Threads int int pthread_create (( pthread_t *thr, *thr, const pthread_attr_t *attr; *attr; void*( *start_routine)(void *), *), void void *arg); pthread_t thr ; variável Identificador Atributos Função Ponteiro p/ parâmetros status Uma thread é uma estrutura de dados tipo pthread_t 3

Exemplo de criação de threads #include <pthread.h> int g; void do_it_1(void *arg) { int i, n= *arg; for(i=0; i < n; i++) g = i; void do_it_2(void *arg) { int i, n= *arg; for(i=0; i < n; i++) printf( %d\n, g); int main( int argc, char **argv) { pthread_t th1, th2; int n = 10; pthread_create(&th1, NULL, do_it_1, &N); pthread_create(&th2, NULL, do_it_2, &N);... Primitivas relacionadas com término (cont.) void voidpthread_join (( pthread_t thread, void void **status); pthread_join (t2) pthread_join (t3) T 1 pthread_exit (status) T 2 pthread_exit ( status ) T 3 Válido apenas para threads com atributo undetached (joinable): é o default! int int pthread_detach (pthread_t thread); Exemplo de espera por threads #include <pthread.h> int g; void do_it_1(void *arg) { int i, n= *(int *)arg; for(i=0; i < n; i++) g = i; void do_it_2(void *arg) { int i, n= *(int *)arg; for(i=0; i < n; i++) printf( %d\n, g); int main( int argc, char *argv) { pthread_t th1, th2; int n = 10; pthread_create(&th1, NULL, do_it_1, &n); pthread_create(&th2, NULL, do_it_2, &n);... pthread_join(th1, NULL); pthread_join(th2, NULL); 4

Algumas outras primitivas... pthread_attr_init ((); ); pthread_attr_setdetachstate (); (); pthread_attr_getdatechstate (); (); pthread_attr_setinheritsched (); (); pthread_attr_getinheritsched (); (); pthread_attr_setschedparam(); pthread_attr_getschedparam (); (); pthread_attr_setschedpolicy (); (); pthread_attr_getschedpolicy (); (); pthread_attr_setscope (); (); pthread_attr_getscope (); (); pthread_attr_setstackaddr (); (); pthread_attr_getstackaddr (); (); pthread_attr_setstacksize (); (); pthread_attr_destroy (); (); The problem with Threads... Thread é uma noção de Sis. Op. Gerenciamento de recursos de HW Posix (ou outras soluções) não fornece um modelo de programação paralela limpo. Programação com threads é complexa; Fácil de cometer erros (deadlocks) É difícil achar os erros!!!!! Ler The trouble with Threads. Lee (Berkeley), IEEE Computer, vol. 36, no. 5, May 2006, pp. 33-42. http://www.eecs.berkeley.edu/pubs/techrpts/2006/eecs-2006-1.html OpenMP (Não perder muito tempo) Idéia central: deixa o compilador se virar para mapear as iterações de laços em threads. Memória compartilhada Paralelismo de laços Compilador. 5

Outras abordagens Paralelismo funcional descreve as tarefas o que executam, quais dados acessam. sincroniza as tarefas explicitamente (sync), ou implicitamente (através dos acessos aos dados). Cria o paralelismo durante a execução Paralelismo baseado num Vetor Global Particionado GPAs SPMD + acesso a dois níveis de memória. Paralelismo Funcional: Cilk Projeto do MIT - Blumofe, Leiserson. começou em 1994, ainda atual. http://supertech.csail.mit.edu/cilk/ leva a programas altamente eficientes cilkchess 1996! Descreve tarefas (tasks) as tarefas acessam variáveis compartilhadas, pode-se disparar tarefas recursivamente gera programas paralelos de tipo Fork/Join. Restringe o modelo de programação! Implementação para memória distribuída... Complicado! Exemplo de programa Cilk cilk int fib (int n) { if (n < 2) return n; else { int x, y; x = spawn fib (n-1); y = spawn fib (n-2); sync; return (x+y); Tirando as palavras chave, recupera-se um programa seqüencial. cilk marca o procedimento como sendo potencialmente executado em paralelo. spawn dispara a execução assíncrona do procedimento. sync sincroniza as threads de execução 6

Acessos concorrentes na memória compartilhada cilk int foo (void) { int x = 0, y; spawn bar(&x); y = x + 1; sync; return (y); cilk void bar (int *px) { printf("%d", *px + 1); return; cilk int foo (void) { int x = 0; spawn bar(&x); x = x + 1; sync; return (x); cilk void bar (int *px) { *px = *px + 1; return; Okay! Problema! Cilk - modelo de programação Cilk suporta o modelo chamado strict parallel computation. Mais ou menos um Divisão & Conquista Grande vantagem: pode-se comprovar que a execução executa com tempo: T p = T 1 /p + T * Como? Escalonamento das tarefas com Work-Stealing. Unified Parallel C Paralelismo baseado num Vetor Global Particionado Projeto que começou nos anos 2000 Berkeley http://upc.lbl.gov/ Mais uma extensão de C... Programação SPMD: fluxos de execução se distribuem o trabalho Trabalho intensivo em nível do compilador. Diferença grande com OpenMP: modo de acessar a memória UPC provê uma memória compartilhada distribuída 7

Exemplo de programa UPC (K. Yelick) #include <upc.h> #include <stdio.h> main() { printf("thread %d of %d: hello UPCworld\n, MYTHREAD, THREADS); Example: Monte Carlo Pi Calculation (K. Yelick) Estimate Pi by throwing darts at a unit square Calculate percentage that fall in the unit circle Area of square = r 2 = 1 Area of circle quadrant = ¼ * π r 2 = π/4 Randomly throw darts at x,y positions If x 2 + y 2 < 1, then point is inside circle Compute ratio: # points inside / # points total π = 4*ratio r =1 Pi in UPC (K. Yelick) Independent estimates of pi: main(int argc, char **argv) { int i, hits, trials = 0; double pi; Each thread gets its own copy of these variables if (argc!= 2)trials = 1000000; else trials = atoi(argv[1]); Each thread can use input arguments srand(mythread*17); for (i=0; i < trials; i++) hits += hit(); pi = 4.0*hits/trials; printf("pi estimated to %f.", pi); Initialize random in math library Each thread calls hit separately 8

Helper Code for Pi in UPC (K. Yelick) Required includes: #include <stdio.h> #include <math.h> #include <upc.h> Function to throw dart and calculate where it hits: int hit(){ int const rand_max = 0xFFFFFF; double x = ((double) rand()) / RAND_MAX; double y = ((double) rand()) / RAND_MAX; if ((x*x + y*y) <= 1.0) { return(1); else { return(0); Acessos na memória Variáveis normais são privadas Declara-se variáveis compartilhadas com a palavra chave shared Pi in UPC: Shared Memory Style Parallel computing of pi, but with a bug shared int hits; main(int argc, char **argv) { int i, my_trials = 0; int trials = atoi(argv[1]); shared variable to record hits divide work up evenly my_trials = (trials + THREADS - 1)/THREADS; srand(mythread*17); for (i=0; i < my_trials; i++) hits += hit(); accumulate hits upc_barrier; if (MYTHREAD == 0) { printf("pi estimated to %f.", 4.0*hits/trials); What is the problem with this program? 9

Shared Arrays Are Cyclic By Default Shared scalars always live in thread 0 Shared arrays are spread over the threads Shared array elements are spread across the threads shared int x[threads] /* 1 element per thread */ shared int y[3][threads] /* 3 elements per thread */ shared int z[3][3] /* 2 or 3 elements per thread */ In the pictures below, assume THREADS = 4 Blue elts have affinity to thread 0 Think of linearized x C array, then map in round-robin y z As a 2D array, y is logically blocked by columns z is not Pi in UPC: Shared Array Version Alternative fix to the race condition Have each thread update a separate counter: But do it in a shared array Have one thread compute sum shared int all_hits [THREADS]; main(int argc, char **argv) { declarations an initialization code omitted for (i=0; i < my_trials; i++) all_hits[mythread] += hit(); upc_barrier; if (MYTHREAD == 0) { all_hits is shared by all processors, just as hits was update element with local affinity for (i=0; i < THREADS; i++) hits += all_hits[i]; printf("pi estimated to %f.", 4.0*hits/trials); UPC Pointers Where does the pointer point? Where does the pointer reside? Private Shared Local PP (p1) SP (p2) Shared PS (p3) SS (p4) int *p1; /* private pointer to local memory */ shared int *p2; /* private pointer to shared space */ int *shared p3; /* shared pointer to local memory */ shared int *shared p4; /* shared pointer to shared space */ Shared to private is not recommended. 10

Common Uses for UPC Pointer Types int *p1; These pointers are fast (just like C pointers) Use to access local data in part of code performing local work Often cast a pointer-to-shared to one of these to get faster access to shared data that is local shared int *p2; Use to refer to remote data Larger and slower due to test-for-local + possible communication int *shared p3; Not recommended shared int *shared p4; Use to build shared linked structures, e.g., a linked list forall & shared arrays If this code were doing nearest neighbor averaging (3pt stencil) the cyclic layout would be the worst possible layout. Instead, want a blocked layout Vector addition example can be rewritten as follows using a blocked layout #define N 100*THREADS shared int [*] v1[n], v2[n], sum[n]; void main() { int i; upc_forall(i=0; i<n; i++; &sum[i]) sum[i]=v1[i]+v2[i]; Affinity All non-array objects have affinity with thread zero. Array layouts are controlled by layout specifiers: Empty (cyclic layout) [*] (blocked layout) [0] or [] (indefinite layout, all on 1 thread) [b] or [b1][b2] [bn] = [b1*b2* bn] (fixed block size) The affinity of an array element is defined in terms of: block size, a compile-time constant and THREADS. Element i has affinity with thread (i / block_size) % THREADS In 2D and higher, linearize the elements as in a C representation, and then use above mapping 11

MFlops per Thread UPC Matrix Vector Multiplication Code Matrix-vector multiplication with matrix stored by rows (Contrived example: problems size is PxP) shared [THREADS] int a[threads][threads]; shared int b[threads], c[threads]; void main (void) { int i, j, l; upc_forall( i = 0 ; i < THREADS ; i++; i) { c[i] = 0; for ( l= 0 ; l< THREADS ; l++) c[i] += a[i][l]*b[l]; NAS FT Variants Performance Summary 1100 1000 900 800 700 600 500 400 300 200 MFlops per Thread Best MFlop rates for all NAS FT Benchmark versions Best NAS Fortran/MPI 1000 Best MPI Best (always NAS Slabs) Fortran/MPI Best UPC Best (always MPIPencils) Best UPC 800 600 400 200.5 Tflops 100 0 0 Myrinet 64 Myrinet 64 InfiniBand 256 InfiniBand 256 Elan3 256 Elan3 256 Elan3 512 Elan3 512 Elan4 256 Elan4 256 Elan4 512 Elan4 512 Joint work with Chris Bell, Rajesh Nishtala, Dan Bonachea UPC HPL Performance GFlop/s 1400 1200 1000 800 600 400 200 X1 Linpack Performance MPI/HPL UPC GFlop/s Opteron Cluster Linpack Performance 200 150 100 MPI/HPL UPC 50 GFlop/s Altix Linpack Performance 160 140 120 100 80 60 MPI/HPL 40 UPC 20 MPI HPL numbers from HPCC database Large scaling: 2.2 TFlops on 512p, 4.4 TFlops on 1024p (Thunder) 0 60 X1/64 X1/128 0 Opt/64 Comparison to ScaLAPACK on an Altix, a 2 x 4 process grid ScaLAPACK (block size 64) 25.25 GFlop/s (tried several block sizes) UPC LU (block size 256) - 33.60 GFlop/s, (block size 64) - 26.47 GFlop/s n = 32000 on a 4x4 process grid ScaLAPACK - 43.34 GFlop/s (block size = 64) UPC - 70.26 Gflop/s (block size = 200) Joint work with Parry Husbands 0 Alt/32 12

Outras APIs de programação paralela Fortress: proposta da SUN para uma nova linguagem paralela, OO, alto-nível (script?), que inclui tratamento de arrays distribuídos. Herdado de HPF. Chapel: proposta da CRAY para uma nova linguagem paralela, OO, alto-nível (script?), que inclui tratamento de arrays distribuídos. Herdado de HPF. Titanium: equivalente do UPC, mas em Java. Tendências... Hoje, OpenMP / MPI são a referência para PP em produção alternativa (?): threads Posix. A comunidade de Compiladores apoia muito GPAs (UPC, Chapel, Fortress...) simplicidade de uso devido ao espaço de endereçamento global, desempenho. A comunidade de Processamento de Alto Desempenho defende muito MPI. A comunidade de Processamento Distribuído defende muito Java RMI. Para usar a hierarquia de memória... Basicamente, não tem nada. MPI: esquece. No sentido de deixa o núcleo se virar com processos pesados. Threads Posix. Pode usar chamadas de sistema, mas será que se quer fazer isso? OpenMP: nada. GPAs: tem o conceito de dois níveis de memória. Idéia: acrescentar OpenMP com diretivas para uso de acessos NUMA? 13