II EPI - Estudo e Avaliação do Problema de Otimização da Multiplicação de Cadeias de Matrizes

1,604 views
1,518 views

Published on

Apresentação realizada na II EPI.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,604
On SlideShare
0
From Embeds
0
Number of Embeds
601
Actions
Shares
0
Downloads
11
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • Explicar o contexto do trabalho:disciplina de Arquitetura de Computadores + disciplina de EDCA do PPGI.
  • Desde 1946, com a criação do primeiro computador eletrônico para fins genéricos (o ENIAC), pode-se perceber a rápida evolução dos processadores ao longo de décadas [1]. A principal razão para tal é a evolução tecnológica que permite cada vez mais a produção eficiente dos transistores. Esta eficiência tem proporcionado a possibilidade de construção de transistores sempre menores e mais baratos, de tal modo que mais ou menos a cada dois anos seu número dobrasse nos processadores, seguindo uma tendência conhecida como Lei de Moore [2]. A rápida evolução dos processadores já é um fator que constantemente tem tornado a execução de programas mais eficiente. Contudo, o aumento da velocidade dos processadores é apenas um dos fatores que podem elevar o desempenho de um programa e, além disto, é limitado por outros fatores que têm influência direta nesta melhoria, dentre eles, a memória [3]. De nada adianta ter processadores super velozes, se a memória não é rápida o suficiente para fornecê-los dados para processamento sem que eles fiquem ociosos. Na década de 80 até meados dos anos 90, ambos evoluíram a uma taxa similar: 1 MHz a 16 MHz. Logo em seguida, a evolução dos processadores continuou a aumentar de forma intensa, ao passo que as taxas de frequência da memória evoluíam em um ritmo mais lento [3]. Deste modo, foi preciso adotar uma nova estratégia para diminuir o tempo de espera do processador: a memória cache. A memória cache é um tipo bastante rápido de memória que serve para armazenar os dados mais frequentemente usados pelo processador, evitando na maioria das vezes que ele tenha que recorrer à “lenta” memória RAM. É interessante perceber o modo de funcionamento da memória cache com o objetivo de usá-las (programaticamente) da maneira mais eficiente possível, como por exemplo, tentar minimizar o cache miss.
  • Sendo assim, é fácil perceber que quando acontece vários cache miss na execução de um programa, seu desempenho tenderá a cair. Os programadores podem utilizar a propriedade da localidade espacial dentre outras relacionadas ao funcionamento da memória cache no intuito de minimizar os cache miss e tornar a execução dos programas mais rápidos.
  • A Figura 1 ilustra o fenômeno da localidade espacial ocorrendo no problema da soma dos elementos de uma matriz. Quando o primeiro elemento da matriz () é buscado para efetuar a soma, o processador buscará um bloco de dados sequencial (uma linha do array, ou parte dela) para a memória cache. Se forem percorridas as linhas da matriz, provavelmente os próximos elementos a serem somados (representados através da cor verde e amarela na Figura 1) estarão na memória cache, o que ocasiona um cache hit, tornando o acesso ao dado mais rápido. Se forem percorridas as colunas, há maior probabilidade de que os próximos elementos a serem somados (vermelho) não estejam na memória cache, ocorrendo um cache miss.
  • II EPI - Estudo e Avaliação do Problema de Otimização da Multiplicação de Cadeias de Matrizes

    1. 1. Estudo e Avaliação do Problema de Otimização da Multiplicação de Cadeias de Matrizes Eduardo de Lucena Falcão Alisson Vasconcelos de Brito Alexandre Nóbrega Duarte
    2. 2. Sumário•Introdução•O Problema da Multiplicação de Cadeias de Matrizes•O Problema do Cache Miss•Análise e Detalhamento de Possíveis Soluções para o Problema deMultiplicação de Cadeias de Matrizes •Abordagem Sequencial •Abordagem com Programação Dinâmica •Abordagem com Minimização do Cache Miss •Abordagem Distribuída com Threads •Abordagem Distribuída com OpenMP•Resultados•Conclusão•Referências
    3. 3. Introdução-Lei de Moore;-Processadores vs Memória RAM-Memória Cache
    4. 4. Introdução- Além de aspectos de hardware como frequência doprocessador e tamanho da memória, é importanteutilizar as estruturas de dados e técnicas de algoritmosque mais se adéquam ao estilo de problema a serresolvido. Adicionalmente, podemos perceber que asescolhas de ferramentas, Linguagens de Programaçãoe APIs também podem ter certo impacto nodesempenho da solução.
    5. 5. Introdução-O objetivo do presente trabalho é tornar evidentes osvários fatores que podem influenciar no desempenhode um programa: -utilizar a memória cache de maneira inteligente; -estruturas de dados e técnicas de programação mais adequados ao problema; -ferramentas e LPs a serem utilizadas.-Para tal, será apresentado o problema daMultiplicação de Cadeias de Matrizes, avaliando seutempo de execução, quando projetado de diferentesmodos.
    6. 6. O Problema da Multiplicação deCadeias 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 multiplicarmossequencialmente as n matrizes obteremos facilmente oresultado 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 aoproblema específico, além de buscar sempre explorar oprocessamento máximo do computador de maneira inteligente.
    7. 7. O Problema do Cache Miss-Acontece quando o processador necessita de um dado, e estenão está na memória cache. Tal fato obriga o processador abuscar um bloco de dados –um número fixo de palavras -diretamente na memória RAM, trazendo-os para a memóriacache e em seguida fornecendo a palavra requerida aoprocessador.-Em razão do fenômeno da localidade espacial, quando umbloco de dados é trazido para a memória cache para satisfazeruma dada referência à memória, é provável que futurasreferências sejam feitas para outras palavras desse bloco[Stallings 2010].
    8. 8. O Problema do Cache Miss-Soma de todos os elementos de uma matriz quadradade tamanho 10000 (Java): -Percorrendo as linhas: 53 ms -Percorrendo as colunas: 2886 ms-Speedup superior a 50 vezes
    9. 9. Análise e Detalhamento de PossíveisSoluções para o Problema de Multiplicaçãode Cadeias de Matrizes-Neste tópico serão descritas algumas abordagenspossíveis para a solução deste problema, que emalguns casos são complementares e em outros sãoantagônicas. -Abordagem Sequencial -Abordagem com Programação Dinâmica -Abordagem com Minimização de Cache Miss -Abordagem Distribuída com Threads -Abordagem Distribuída com OpenMP
    10. 10. Abordagem Sequencial-Multiplicam-se sequencialmente as n matrizes paraobter seu produto.-Ex.: para uma cadeia com quatro matrizes a ordem demultiplicação seria-Complexidade: - , sendo n o tam. das matrizes; ou - , para t matrizes 1 for(int i=0; i<a.length ;i++){ 2 for(int j=0; j<b[0].length ;j++){ 3 c[i][j] = 0; 4 for(int k=0; k<a[0].length ;k++) 5 c[i][j] += a[i][k] * b[k][j]; 6 } 7 }
    11. 11. Abordagem com ProgramaçãoDinâmica-Analisando mais cuidadosamente o código da Tabela anterior,pode-se perceber que o número de multiplicações escalaresrelacionadas à multiplicação de duas matrizes respeita oseguinte cálculo:-O referente à multiplicação pode ser descrito de maneira maisdetalhada por-Sendo assim, pode-se observar que a ordem com que as matrizes sãomultiplicadas pode tornar o programa mais eficiente, ou seja, reduzir onúmero de multiplicações.
    12. 12. Abordagem com ProgramaçãoDinâmica-Por ex., para multiplicar uma cadeia de matrizes contendo trêsmatrizes existem duas parentizações possíveis.-Ex.: Nº de mult. Ordem de mult. escalares 1 75000 2 7500-Speedup de 10x. É interessante perceber que para o exemplo anterior aabordagem sequencial é a mais rápida. Mas, deve ser ressaltado que isso foiapenas uma coincidência, e que a probabilidade da abordagem sequencialser a mais rápida torna-se bastante remota quando o número de matrizes dacadeia aumenta, o que proporciona um ganho expressivo quando se utiliza aabordagem com a parentização otimizada.
    13. 13. Abordagem com ProgramaçãoDinâ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çãoda estratégia de Programação Dinâmica.-A Programação Dinâmica (PD) geralmente é aplicada a problemas deotimização, ou seja, problemas que possuem várias soluções, mas deseja-seencontrar uma solução ótima, como é o caso do corrente problema. Paraaplicar a PD ao problema da multiplicação de cadeias de matrizes sãonecessá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 apartir das informações coletadas. Mais detalhes sobre descrição eimplementação desse problema através da PD são fornecidos em [Cormen et
    14. 14. Abordagem com Minimizaçãodo Cache Miss-Com relação ao problema de multiplicação de matrizes, deve-seprimeiramente ressaltar que a própria natureza de seu algoritmo o faz maissuscetível à ocorrência de cache miss. Pois é sabido que para multiplicarduas matrizes, deve-se percorrer a linha da primeira e a coluna da segunda,e quando se percorre a coluna de uma matriz a probabilidade de ocorrênciado cache miss aumenta.-Baseado no funcionamento do algoritmo, observou-se que é possívelminimizar a ocorrência do cache miss invertendo as linhas 1 e 2 da Tabela 1(quando pertinentes), com o objetivo de que o programa reutilize dadospreviamente armazenados na memória cache. 1 for(int i=0; i<a.length ;i++){ 2 for(int j=0; j<b[0].length ;j++){ 3 c[i][j] = 0; 4 for(int k=0; k<a[0].length ;k++) 5 c[i][j] += a[i][k] * b[k][j]; 6 } 7 }
    15. 15. Abordagem com Minimizaçãodo Cache Miss-Pensou-se o seguinte: se a quantidade de linhas da primeira matriz é maiorque a quantidade de linhas da segunda matriz, deve-se manter o código daTabela 1, caso contrário, devem ser invertidas as linhas 1 e 2 da Tabela 1.Com essa verificação, o algoritmo sempre percorrerá a “maior linhapossível”, o que minimiza o cache miss. if(a.length > b.length) <Código da Tabela 1> else <Código da Tabela 1 com linhas 1 e 2 invertidas> 1 for(int i=0; i<a.length ;i++){ 2 for(int j=0; j<b[0].length ;j++){ 3 c[i][j] = 0; 4 for(int k=0; k<a[0].length ;k++) 5 c[i][j] += a[i][k] * b[k][j]; 6 } 7 }
    16. 16. Abordagem com Minimizaçãodo Cache Miss-Outra maneira de se reduzir o cache miss para o problema da multiplicaçãode matrizes seria multiplicar a primeira matriz pela matriz transposta dasegunda. Pode-se perceber que para isto seria necessário mudar o códigorelativo à multiplicação das matrizes: ao invés de multiplicar linhas daprimeira matriz por colunas da segunda, multiplicar-se-iam linhas daprimeira matriz por linhas da segunda, o que implicaria numa reduçãosignificativa do cache miss. Para evitar um custo adicional para o cálculo datransposta da segunda matriz, poderia apenas ser alterado o método decriação das mesmas para já criá-las como sendo suas próprias transpostas.
    17. 17. Abordagem Distribuída comThreads-A abordagem distribuída utilizando threads visa explorar a potencialidademáxima dos processadores atuais, que geralmente possuem mais de umnúcleo físico e/ou lógico. Contudo, a abordagem distribuída com threadsutilizada no presente trabalho não caracteriza uma solução ótima, apesar deexplorar a capacidade máxima do hardware.- A estratégia utilizada para esta abordagem divide a cadeiapelo número de threads a serem criadas. Desse modo, cada thread ficaencarregada de realizar a multiplicação de uma sub-cadeia, e ao final,quando todas terminarem sua execução, a thread principal realizará amultiplicação das matrizes resultantes.
    18. 18. Abordagem Distribuída comThreads-Como exemplo, considere uma cadeia com doze matrizesutilizando a abordagem distribuída com duas threads. Esta cadeia seriaquebrada ao meio em duas sub-cadeias e ,e depois passaria pelo processo de se encontrar a parentização ótima atravésda estratégia de PD. Porém, é fácil perceber que a parentização ótima para acadeia muito dificilmente será alcançada com a divisão dacadeia. Para alcançarmos tanto a parentização ótima e ainda explorar acapacidade máxima do processador outra estratégia deve ser utilizada, comopor exemplo, a abordagem distribuída utilizando a biblioteca OpenMP.
    19. 19. Abordagem Distribuída comOpenMP-A abordagem distribuída 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ãointerpretadas pelo compilador, e que ao executar o programa, ativam asthreads dos processadores de acordo com as mesmas. Portanto, o trecho decódigo que se pretende distribuir deve ser minuciosamente estudado paraque nenhuma violação lógica ou física seja cometida.-Para o problema da multiplicação de matrizes, foi percebido que oselementos da matriz resultante não possuem interdependências, o quepossibilita a paralelização desse trecho de código, mais especificamente doloop for da linha 1. 1 for(int i=0; i<a.length ;i++){ 2 for(int j=0; j<b[0].length ;j++){ #pragma omp parallel for 3 c[i][j] = 0; 4 for(int k=0; k<a[0].length ;k++) <Código da Tabela 1> 5 c[i][j] += a[i][k] * b[k][j]; 6 } 7 }
    20. 20. Abordagem Distribuída comOpenMP-A biblioteca OpenMP usa o modelo de paralelismo fork-and-join, que ramifica athread principal em threads paralelas, e quando estas terminam de executar, a threadprincipal reassume o controle do programa [Chandra et al 2001]. Existem diversasdiretivas da biblioteca OpenMP que permitem os programadores tornarem seusprogramas distribuídos. A diretiva que foi utilizada atua de forma simples, elasubdivide a quantidade total de iterações no loop for pelo número de threads aserem utilizadas, e cada thread executará uma parte das iterações que antes eramexecutadas por apenas uma thread. No problema da multiplicação de matrizes, se amatriz resultante tiver 10 linhas, e for especificado que o processador deve trabalharcom duas threads, a primeira computará o produto das 5 primeiras linhas da matrizresultante, e a segunda computará as linhas restantes.
    21. 21. Resultados-Para avaliar algumas das abordagens estudadas pensou-se em realizar cincoexperimentos, aliando diferentes algoritmos e técnicas de programação.1.Linguagem de Programação Java: a) Abordagem sequencial, “maximizando o cache miss”; b)Utilizando técnicas de PD, “maximizando o cache miss”; 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 distribuída em 2 Threads; e)Utilizando técnicas de PD, minimizando o cache miss, além de tornar a lógica do algoritmo distribuída em 4 Threads;-“Maximizar o cache miss” tem o objetivo de tornar mais evidente a ocorrência domesmo, e prover uma noção de tempo desperdiçado quando o mesmo ocorre. Paraminimizar o cache miss foi utilizada o código explicado anteriormente (slide 15). Epara tornar a lógica do algoritmo distribuído foi utilizada a abordagem distribuídacom threads. Para fins de padronização as matrizes foram preenchidas com 1’s.
    22. 22. Resultados-Para tais experimentos, foi utilizado um notebook Dell Vostro 3450, SistemaOperacional Windows 7 Professional Service Pack 1 de 64 Bits, 4 GB dememó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-Pode-se perceber que todas as matrizes da cadeia possuem o número de linhasmuito superior ao número de colunas, ou justamente o inverso, pois a ocorrência decache miss torna-se mais acentuada nesses casos.
    23. 23. Resultados1.Linguagem de Programação Java: a) Abordagem sequencial, “maximizando o cache miss”; b)Utilizando técnicas de PD, “maximizando o cache miss”; 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 distribuída em 2 Threads; e)Utilizando técnicas de PD, minimizando o cache miss, além de tornar a lógica do algoritmo distribuída em 2 Threads; 36.7 40 35 1.a 30 1.b 25 1.c 20 1.d 15 10.9 6.2 6.6 6.4 1.e 10 5 0-Diferença de desempenho da abordagem que usa PD para a sequencial  25.8 s-Pode-se notar que quando é utilizada uma estratégia de minimização de cache miss obteve-se4.7 segundos de speedup, que representa uma evolução de quase 50%-Ao analisar a estratégia distribuída com threads, pode-se perceber que tanto utilizando 2 como4 threads, houve perda de desempenho
    24. 24. Conclusão- O objetivo do presente trabalho foi mostrar a importância de dominar técnicasrelacionadas a projeto de algoritmos, e também conceitos de arquitetura decomputadores para obter melhor desempenho do software e hardware. Ao utilizar atécnica de PD aliada à minimização de cache miss, obteve-se um speedup de 6x emrelação ao desempenho da solução mais simples (sequencial). É interessanteperceber 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égiade solução mais eficiente. Para tal, devem ser analisados os algoritmospertinentes, ferramentas (APIs, bibliotecas, etc.) e LPs a serem utilizadas, além deconceitos sobre funcionamento de software/hardware, de sistemas operacionais e daarquitetura do computador de uma forma generalizada.
    25. 25. Trabalhos FuturosComo possibilidades para trabalhos futuros, pode ser considerada a implementaçãodas abordagens já citadas na LP C++, uma vez que geralmente os programas escritosnessa LP tendem a ter melhor desempenho que em Java. Além disso, a abordagemDistribuída com OpenMP parece ser a mais eficiente. O fato de aproveitar odesempenho da LP C++, realizando a distribuição do algoritmo em quantas threadsdesejar, mantendo a parentização ótima alcançada pela PD, e minimizar a ocorrênciade cache miss com a abordagem da matriz transposta, aparenta ser a melhor soluçãoanalisada no presente trabalho. Outra tarefa interessante seria implementar osalgoritmos para multiplicação de matrizes desenvolvidos por Strassen, que possuicomplexidade de , ou o desenvolvido por Coppersmith e Winograd comordem de complexidade , aliando à alguma abordagem de minimização de cache misspara comparação dos resultados [Robinson 2005].
    26. 26. Referências- Koomey, J. G., Berard, S., Sanchez, M., Wong, H. (2009) “Assessing Trends in theElectrical Efficiency”. Final report to Microsoft Corporation and Intel Corporation.- Schaller, R. R. “Moores law: past, present and future”. (1997) IEEE Spectrum, Vol34, 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 PrenticeHall, 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. “ParallelProgramming 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.
    27. 27. Obrigado! Perguntas?

    ×