PROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdf
Aula 1 - Estudando o problema a ser resolvido
1. Introdução a Sistemas Distribuídos
Estudando o Problema a ser
Resolvido
Eduardo de Lucena Falcão
2. Introdução
● Na maioria das vezes, qual a nossa atitude quando nos
deparamos com um problema de programação?
3. Otimização do Programa
Em ordem de importância:
1. O algoritmo: estruturas de dados e técnicas de algoritmos
mais adequadas ao problema;
2. Software: Linguagens de Programação e APIs;
3. Hardware: frequência do processador, e capacidade de
memória.
*1 única instância de processamento
4. Otimização do Programa
● Preciso melhorar ainda mais meu tempo de execução!
● Tornar distribuído o algoritmo que já era paralelo.
– Ex.: Map-Reduce
5. Objetivo da Aula
● Exemplo Prático de um problema simples
– Multiplicação de Cadeias de Matrizes
● Multiplicação de Matrizes
● Tornar evidente em números, o que a análise e estudo do
problema pode nos proporcionar (tempo de execução).
● Efeito bola de neve! (quando não tiramos maior proveito de
nosso algoritmo)
6. O Problema da Multiplicação de
Cadeias de Matrizes
● Entrada: cadeia com n matrizes
● Saída: matriz resultante do produto das n matrizes
● O problema em sua essência é trivial, pois se multiplicarmos
sequencialmente as n matrizes obteremos facilmente o
resultado esperado. O maior desafio que reside neste
problema é otimizar o desempenho do programa que o
resolve. Para tal, podemos explorar técnicas de programação
aplicadas ao problema específico, além de buscar sempre
explorar o processamento máximo do computador de maneira
inteligente.
10. Abordagem Sequencial
● Multiplicam-se sequencialmente as n matrizes
para obter seu produto.
● Ex.: para uma cadeia com quatro matrizes a ordem de
multiplicação seria: .
● Complexidade:
– , sendo n o tamanho (linha de A, coluna de A, coluna
de B)das matrizes.
for(inti= 0;i< a.length;i+ + ){
for(intj= 0;j< b[0].length;j+ + ){
c[i][j]= 0;
for(intk= 0;k< a[0].length;k+ + )
c[i][j]+ = a[i][k]* b[k][j];
}
}
11. E o problema do Cache Miss?
● Acontece quando o processador necessita de um dado,
e este não está na memória cache. Tal fato obriga o
processador a buscar um bloco de dados –um número
fixo de palavras - diretamente na memória RAM,
trazendo-os para a memória cache e em seguida
fornecendo a palavra requerida ao processador.
● Em razão do fenômeno da localidade espacial, quando
um bloco de dados é trazido para a memória cache para
satisfazer uma dada referência à memória, é provável
que futuras referências sejam feitas para outras palavras
desse bloco. [Stallings 2010]
12. E o problema do Cache Miss?
● Soma de todos os elementos de uma matriz
quadrada de tamanho 10000 (Java):
– Percorrendo as linhas: 53 ms;
– Percorrendo as colunas: 2886 ms.
● Speedup superior a 50 vezes.
13. E o que o Cache Miss interfere em
nosso problema?
● Onde há matrizes *pode* haver cache miss;
● Sempre devemos ficar atentos quando estivermos
trabalhando com matrizes, objetivando o cache hit;
● É natural que ocorra o cache miss para o problema de
multiplicação de matrizes, pois é inerente a seu
algoritmo;
● Mas é possível *tentar* burlar o cache miss para este
problema de algumas maneiras.
14. Abordagem com Minimização de
Cache Miss
● Que tal multiplicar a primeira matriz pela matriz transposta da segunda?
Pode-se perceber que para isto seria necessário mudar o código relativo à
multiplicação das matrizes: ao invés de multiplicar linhas da primeira
matriz por colunas da segunda, multiplicar-se-iam linhas da primeira
matriz por linhas da segunda, o que implicaria numa redução
significativa do cache miss. Para evitar um custo adicional para o cálculo
da transposta da segunda matriz, poderia apenas ser alterado o método
de criação das mesmas, para já criá-las como sendo suas próprias
transpostas.
15. Quanto às *Cadeias* de Matrizes?
● Quanto às cadeias: o que podemos fazer para otimizar
nosso programa?
– Resp.: utilizar a Programação Dinâmica
● Analisando mais cuidadosamente o código da
multiplicação de matrizes, pode-se perceber que o
número de multiplicações escalares relacionadas à
multiplicação de duas matrizes respeita o seguinte
cálculo:
16. Abordagem com Programação Dinâmica
● O referente à multiplicação pode ser descrito de
maneira mais detalhada por:
● Sendo assim, pode-se observar que a ordem com que as
matrizes são multiplicadas pode tornar o programa mais
eficiente, ou seja, reduzir o número de multiplicações.
● Por ex., para multiplicar uma cadeia de matrizes contendo
três matrizes existem duas parentizações possíveis.
– Ex.: Ordem de mult. Nº de mult. escalares
1 75000
2 7500
17. Abordagem com Programação Dinâmica
● Speedup de 10x. É interessante perceber que para o
exemplo anterior a abordagem sequencial é a mais rápida.
Mas, deve ser ressaltado que isso foi apenas uma
coincidência, e que a probabilidade da abordagem sequencial
ser a mais rápida torna-se bastante remota quando o número
de matrizes da cadeia aumenta, o que proporciona um ganho
expressivo quando se utiliza a abordagem com a
parentização otimizada.
Ordem de mult. Nº de mult. escalares
1 75000
2 7500
18. Abordagem com Programação Dinâmica
● Mas como proceder para encontrar a parentização otimizada?
● Através da força bruta, o nº de soluções seria exponencial em n ( ), sendo n
o número de multiplicações, tornando essa verificação inviável [Cormen et al
2002]. Uma alternativa viável para este problema é a utilização da estratégia de
Programação Dinâmica.
● A Programação Dinâmica (PD) geralmente é aplicada a problemas de otimização,
ou seja, problemas que possuem várias soluções, mas deseja-se encontrar uma
solução ótima, como é o caso do corrente problema. Para aplicar a PD ao
problema da multiplicação de cadeias de matrizes são necessárias quatro etapas:
caracterizar a estrutura de uma solução ótima, que nesse caso é a estrutura de
uma colocação ótima dos parênteses; definir recursivamente o valor de uma
solução ótima para o problema; calcular o valor de uma parentização ótima;
construir a solução ótima a partir das informações coletadas. Mais detalhes sobre
descrição e implementação desse problema através da PD são fornecidos em
[Cormen et al 2002].
19. Abordagem Paralela com Threads
● A abordagem paralela utilizando threads visa explorar a
potencialidade máxima dos processadores atuais, que
geralmente possuem mais de um núcleo físico e/ou lógico.
Contudo, a abordagem paralela com threads apresentada
aqui não caracteriza uma solução ótima, apesar de explorar a
capacidade máxima do hardware.
● A estratégia utilizada para esta abordagem divide a cadeia
pelo número de threads a serem criadas. Desse
modo, cada thread fica encarregada de realizar a
multiplicação de uma sub-cadeia, e ao final, quando todas
terminarem sua execução, a thread principal realizará a
multiplicação das matrizes resultantes.
20. Abordagem Paralela com Threads
● Como exemplo, considere uma cadeia com doze matrizes
utilizando a abordagem distribuída com duas
threads. Esta cadeia seria quebrada ao meio em duas
sub-cadeias e , e depois
passaria pelo processo de se encontrar a parentização ótima
através da estratégia de PD. Porém, é fácil perceber que a
parentização ótima para a cadeia muito
dificilmente será alcançada com a divisão da cadeia. Para
alcançarmos tanto a parentização ótima e ainda explorar a
capacidade máxima do processador outra estratégia deve ser
utilizada, como por exemplo, a abordagem paralela utilizando a
biblioteca OpenMP.
21. Abordagem Paralela com OpenMP
● A abordagem paralela utilizando a biblioteca OpenMP (Open
Multi-Processing) não divide a cadeia de matrizes em
sub-cadeias, e portanto, mantém a parentização otimizada
encontrada através da abordagem por PD. Ao invés disso,
utilizam-se diretivas em trechos de código que são
interpretadas pelo compilador, e que ao executar o programa,
ativam as threads dos processadores de acordo com as
mesmas. Portanto, o trecho de código que se pretende
distribuir deve ser minuciosamente estudado para que
nenhuma violação lógica ou física seja cometida.
22. Abordagem Paralela com OpenMP
● Para o problema da multiplicação de matrizes, foi
percebido que os elementos da matriz resultante não
possuem interdependências, o que possibilita a
paralelização desse trecho de código, mais
especificamente do loop for da linha 1.
# pragm a om p parallelfor
for(inti= 0;i< a.length;i+ + ){
for(intj= 0;j< b[0].length;j+ + ){
c[i][j]= 0;
for(intk= 0;k< a[0].length;k+ + )
c[i][j]+ = a[i][k]* b[k][j];
}
}
23. Abordagem Paralela com OpenMP
● A biblioteca OpenMP usa o modelo de paralelismo fork-and-join, que ramifica a
thread principal em threads paralelas, e quando estas terminam de executar, a
thread principal reassume o controle do programa [Chandra et al 2001]. Existem
diversas diretivas da biblioteca OpenMP que permitem os programadores tornarem
seus programas distribuídos. A diretiva que foi utilizada atua de forma simples, ela
subdivide a quantidade total de iterações no loop for pelo número de threads a
serem utilizadas, e cada thread executará uma parte das iterações que antes eram
executadas por apenas uma thread. No problema da multiplicação de matrizes, se
a matriz resultante tiver 10 linhas, e for especificado que o processador deve
trabalhar com duas threads, a primeira computará o produto das 5 primeiras linhas
da matriz resultante, e a segunda computará as linhas restantes.
24. Resultados
● Para tais experimentos, foi utilizado um notebook Dell
Vostro 3450, Sistema Operacional Windows 7 Professional
Service Pack 1 de 64 Bits, 4 GB de memória RAM,
processador Intel® Core™ i5-250M de 2.5 GHz.
● A cadeia de matrizes escolhida para os experimentos foi a
seguinte:
<7000,50,30,5000,32,40,5000,80,20,4000,20,10,1000,50>, o
que equivale às matrizes
25. Resultados
● Linguagem de Programação Java:
a) Abordagem sequencial;
b) Utilizando técnicas de PD;
c) Utilizando técnicas de PD, minimizando o cache miss;
d) Utilizando técnicas de PD, minimizando o cache miss, além de tornar a lógica do algoritmo
paralela em 2 Threads;
e) Utilizando técnicas de PD, minimizando o cache miss, além de tornar a lógica do algoritmo
paralela em 4 Threads.
0
5
10
15
20
25
30
35
40 36,7
10,9
6,2 6,6 6,4
26. Qual o Aprendizado?
● O objetivo dessa aula foi mostrar a importância de dominar técnicas
relacionadas a projeto de algoritmos, e também conceitos de arquitetura
de computadores para obter melhor desempenho do software e
hardware. Ao utilizar a técnica de PD aliada à minimização de cache
miss, obteve-se um speedup de 6x em relação ao desempenho da
solução mais simples (sequencial). É interessante perceber que todos os
algoritmos estão na mesma ordem de complexidade de tempo ( ), e
mesmo assim foram obtidos ganhos de desempenho.
● Destes resultados, pode-se colher como aprendizado, que ao receber um
problema é necessário estudá-lo, visualizá-lo de diferentes perspectivas
para adotar a estratégia de solução mais eficiente. Para tal, devem ser
analisados os algoritmos pertinentes, ferramentas (APIs, bibliotecas, etc.)
e LPs a serem utilizadas, além de conceitos sobre funcionamento de
software/hardware, de sistemas operacionais e da arquitetura do
computador de uma forma generalizada.
27. Qual a aplicação disso em nosso curso?
● Devemos sempre tentar fazer o mesmo antes de partir
para a estratégia Distribuída!
● Caso contrário, todos esses segundos ou milissegundos
que se acumularam, se tornarão uma bola de neve
quando milhares de requisições forem feitas a seu
sistemas.
● E isso lhe custará dinheiro, muito dinheiro!!
28. Referências
● Koomey, J. G., Berard, S., Sanchez, M., Wong, H. (2009) “Assessing Trends in the Electrical
Efficiency”. Final report to Microsoft Corporation and Intel Corporation.
● Schaller, R. R. “Moore's law: past, present and future”. (1997) IEEE Spectrum, Vol 34, pp.
52-59.
● Alted, F. “Why Modern CPUs are Starving and what can be done about it”. (2010)
Computing in Science & Engineering, pp. 68–71.
● Stallings, W. “Arquitetura e Organização de Computadores”. (2010) Editora Prentice Hall,
pp. 122-144.
● Cormen, T. H., Leiserson, C. E., Rivest, R. L., Stein, C. “Algoritmos: Teoria e Prática”. (2002)
Editora Campus, pp. 259-295.
● Chandra, R., Dagum, L., Kohr, D., Maydan, D., McDonald, J., Menon, R. “Parallel
Programming in OpenMP”. (2001) Editora Morgan Kaufmann.
● Robinson, S. “Toward an Optimal Algorithm for Matrix Multiplication”. (2005) Society for
Industrial and Applied Mathematics. Vol. 38, Nº 9.