Você está na página 1de 14
Universidade Federal de Ouro Preto Instituto de Ciências Exatas e Aplicadas Departamento de Computação e

Universidade Federal de Ouro Preto

Instituto de Ciências Exatas e Aplicadas

Departamento de Computação e Sistemas

Redução de complexidade usando paralelismo

Matheus Fellipe do Carmo Barros Daniel Goldner Junior Daniel Araújo Vinícius Linhares

Professor - Fabianni Roberto Teles

João Monlevade

2018

SUMÁRIO

1 Introdução

2

2 Paralelismo

2

3 Redução complexidade

5

4 Exemplos

7

5 Conclusão

11

6 Referências

12

1

- Introdução

Os problemas com custo fatorial ou combinatório estão agrupados em uma classe de complexidade não determinística polinomial - NP. Estes problemas não têm, em geral, uma metodologia de solução prática, o que significa dizer que uma máquina não pode resolvê-los em um tempo razoável, mesmo em pequenos tamanhos (instâncias pequenas do problema). Assim, na teoria da complexidade, os problemas estão divididos em várias classes de complexidade de acordo com os tempos de execução em um sistema de processador único (ou uma máquina de Turing determinística, para ser mais exato). Problemas cujo tempo de execução é polinomial pertencem à classe P e são considerados tratáveis. Por outro lado, há problemas que mesmo utilizando o melhor algoritmo determinístico conhecido ainda possui um tempo de execução exponencial, e por isso são intratáveis. Neste cenário, mostrar que existe uma forma de reduzir a complexidade de problemas através de uma técnica e que esta pode ser aplicada à maior parte dos problemas, ou mesmo a todos eles, poderia colocar as pesquisas ligadas a resolução de problemas em um nível mais elevado. Inúmeras são as abordagens que buscam reduzir a complexidade descrita, inclusive através da combinação de várias estratégias e técnicas. Entre estas abordagens está a computação paralela.

2 - Paralelismo

Têm-se constatado a crescente oferta de equipamentos que proporcionam ambientes de programação paralela, como os agregados de computadores, conhecidos como clusters. Reúnem-se várias máquinas, como computadores pessoais (PCs), através de uma rede de comunicação de alto desempenho, tendo assim um ambiente de programação paralela ou distribuída. Nesses ambientes, o poder computacional tem aumentado tanto pelo aumento da velocidade de processamento dos processadores quanto pelo aumento do número de processadores integrados ou agregados ao sistema. Neste contexto, é necessário caracterizar a forma de se executar tarefas conhecida como processamento que pode ser sequencial, pipeline, vetorial, paralelo e distribuído.

2.1 - Processamento sequencial

O processador lê um único fluxo de dados por vez e realiza uma operação por unidade de tempo, ou seja, não se executa mais que uma operação por unidade de

tempo.

2.2 - Processamento pipeline

Pipeline é a divisão de uma função genérica em uma seqüência de k sub-funções que podem ser implementadas por k módulos de hardware dedicados e autônomos denominados estágios. Cada estágio é capaz de receber dados do estágio anterior, operá-los e transmitir o resultado para o estágio seguinte. Dessa forma, sucessivas execuções da função podem ser conduzidas pelas sub-funções, operando por superposição (overlap),resultando no processamento pipeline.

2.3 - Processamento

vetorial

Substitui-se um laço do programa que usa instruções escalares por um laço que usa instruções vetoriais, levadas a cabo por um hardware específico, implementado por pipeline. O processamento vetorial difere no fato de que os pipelines evoluíram para instruções vetoriais.

2.4 - Processamento paralelo

É uma forma eficiente de processar informação a qual enfatiza a exploração de eventos concorrentes na computação do processo. Pode-se caracterizar o processamento paralelo quando existe um conjunto de máquinas sendo controladas por um único sistema operacional. A realização de tarefas é levada a cabo por determinação desse sistema que diz quem realiza o que.

2.5 - Processamento distribuído

No processamento distribuído há um conjunto de máquinas, cada uma com seu próprio sistema operacional. Existem diversos processadores, diferentes ou não, utilizando uma rede de comunicação. Os processadores trabalham cooperativamente para que os recursos dispersos sejam utilizados na prestação de serviços. Esses diversos processadores devem controlar os seus próprios recursos.

2.6 - Programação Paralela

O paralelismo pode ser implícito ou explícito. O paralelismo implícito é tido como

aquele que é inerente ao próprio programa. Esse tipo de paralelismo, geralmente, é identificado pelo sistema operacional. Portanto, cabe ao sistema operacional fazer a análise de dependências, visando identificar partes ou pedaços do programa que podem ser processados ao mesmo tempo, ou seja, podem ser paralelizados. A independência é dada pela necessidade de acesso exclusivo aos dados. Cabe ao Sistema Operacional e/ou compilador:

● Detectar o paralelismo potencial do sistema;

● Atribuir as tarefas para execução em paralelo;

● Controlar e sincronizar toda execução.

O paralelismo implícito tem como vantagens e/ou desvantagens:

● Libera o programador dos detalhes da execução paralela;

● Solução mais geral e mais flexível;

● Difícil conseguir uma solução mais eficiente para todos os casos.

O paralelismo explícito pode aparecer em três formas:

• Paralelismo através de dados (data paralellism)- muito comum em arquiteturas

matriciais, onde uma única instrução é executada por vários elementos processadores sobre diversos fluxos de dados;

• Paralelismo por troca de mensagens (message passing)- são encontrados em

arquiteturas de multiprocessadores, onde vários processadores estão envolvidos na execução do programa, sendo necessário que se comuniquem. Nesses casos a maior parte do processamento é local, mas há uma pequena parte do processamento que consiste em troca de informação;

• Paralelismo através de variáveis comuns - também encontrado em arquiteturas

de multiprocessadores, onde a comunicação se faz através de variáveis comuns (memória global), as quais substituem mecanismos de comunicação, onde os processos trocam de informação através de acessos à memória, o que proporciona uma comunicação rápida. Cabe ao programador:

● Anotar as tarefas para execução em paralelo;

● Atribuir as tarefas aos processadores;

● Controlar a execução;

● Conhecer a arquitetura da máquina de forma a obter melhor performance.

O paralelismo explícito tem como vantagens e/ou desvantagens:

● Depende da experiência e capacidade do programador;

● Dificuldade de portabilidade entre diferentes arquiteturas.

3 - Redução Complexidade

Devido aos limites físicos dos recursos disponíveis no computador, não basta identificar um problema e garantir que exista pelo menos uma solução para este, é necessário saber se este pode ser resolvido efetivamente dentro de certos limites referentes a tais recursos. A complexidade computacional consiste em uma função matemática que depende do tamanho da entrada e dos recursos utilizados pelo algoritmo, sendo o tempo e o espaço (quantidade de memória) os recursos que comumente são avaliados para mensuração da mesma, em outras palavras, segundo Hwang e Jotwani (2010, p 30) a complexidade de um algoritmo para resolver um problema de tamanho s em um computador é determinada pelo tempo de execução e pelo espaço requerido. Complexidade de tempo Denominada também de complexidade temporal, ela consiste em uma função que varia de acordo com o tamanho da entrada para o problema, sendo mensurada pelo número de unidades de tempo necessárias a execução do algoritmo Complexidade de espaço Também chamada de complexidade espacial, ela refere-se à quantidade de memória requerida pelo algoritmo como uma função do tamanho do problema, sendo mensurada como uma unidade de espaço para cada registro necessário para um cálculo individual Ao estudar a complexidade de um algoritmo pode-se avaliá-la sobre a ótica de que o algoritmo proposto para resolver o problema poderá solucioná-lo em 3(três) diferentes cenários, sendo eles:

Várias são as métricas utilizadas para analisar um algoritmo paralelo, destacando-se:

tempo de execução; overhead; speedup; eficiência e custo. Exemplo:

O problema consiste em achar um determinado elemento x em uma lista L de n

, precisamente, dado um número x em uma lista L qualquer, encontrar um índice j tal que L[j] = x.

elementos ordenados ou não ordenados, onde L = (a1, a2,

an), ou mais

Para efeito de análise será abordado apenas o caso em que os elementos da lista

Para efeito de análise será abordado apenas o caso em que os elementos da lista L estão desordenados,O Algoritmo 1 realiza este processo de forma sequencial, possuindo complexidade de tempo igual a O (n), para o pior caso. Para construção do algoritmo paralelo para o problema da pesquisa utilizamos uma técnica de busca em blocos de elementos, no qual um conjunto de p processadores, fará uma pesquisa em um bloco de tamanho b, onde b = p, em d iterações, sendo d = log n, onde:

b, onde b = p, em d iterações, sendo d = log n, onde: sendo p

sendo p uma função de qualidade fp(n) a qual determina o número de unidades de processamento(threads) utilizadas e que garantirão a redução de complexidade pretendida, em uma lista de n elementos

O Algoritmo 2 realiza o processo de pesquisa, particionando a lista L em blocos de

elementos de tamanho b, onde cada thread irá verificar um elemento do bloco. A

variável k é compartilhada por todas as threads, tendo sido atribuído o valor (-1) a ela, indicando que o elemento não foi encontrado. Assim, quando alguma thread encontrar

o valor que está sendo procurado, esta variável é modificada, indicando em que

posição da lista L ele se encontra, forçando todas as demais threads a cessarem a busca, conforme linhas 5 e 8. O processo irá ser realizado, no pior caso, até que toda a lista seja verificada ou até o elemento ser encontrado, ou seja, emlog npassos.

Analisando agora a quantidade de iterações necessárias para percorrer todo o conjunto de elementos de

Analisando agora a quantidade de iterações necessárias para percorrer todo o conjunto

de elementos de L, está é expressa por O(log n) passos, logo têm-se que:

O(Pesquisa) = O(Computações por Nível) x O(Iterações) O(Pesquisa) = O(1).O(log n) O(Pesquisa) = O(log n), para o pior caso. Há uma redução na ordem de grandeza da complexidade de tempo do Problema da Pesquisa, haja vista que o melhor algoritmo seqüencial para o referido problema é O(n), enquanto o algoritmo paralelo descrito (ALGORITMO 2) possui complexidade O(log n).

4 - Exemplos

Para fazer uma comparação de complexidade, foi se estudado o algoritmo do

Crivo de Eratóstenes, que é um algoritmo clássico para encontrar todos os números primos menores ou iguais a um número inteiro positivo n.

O estudo consiste na comparação entre o algoritmo executado de forma serial e

paralelo, usando um número p de processadores.

4.1 -Crivo de Ertóstenes

O Crivo de Eratóstenes (276 A.C. - 194 A.C.) é um método simples e prático de

se encontrar números primos até um certo valor limite n. O algoritmo começa com a

lista de números naturais de 2 até n . A cada passo, o menor fator primo (ainda não

utilizado) p é escolhido e todos os múltiplos de p são removidos da lista. O algoritmo termina quando todos os fatores primos menores ou iguais a √ntenham sido utilizados. A ideia do algoritmo usado é passar como parâmetro um determinado número n, e como resultado se obtém o número de números primos do intervalo de 2 até n.

4.2 - Algoritmo Serial

resultado se obtém o número de números primos do intervalo de 2 até ​ n .

4.2.1 - Análise de Complexidade

A análise de complexidade do algoritmo levará em conta o limite superior n da lista de primos.

Tempo: a complexidade de tempo T(n) do Crivo de Eratóstenes no pior caso, melhor caso e caso médio é:

T(n) =O(n*log log n)

Espaço: a complexidade de espaço E(n) do algoritmo no pior caso, melhor caso e caso médio é:

E(n)=O(n)

4.3 - Algoritmo Paralelo

O paralelismo do Crivo de Eratóstenes consiste em dividir a entrada entre os processos, assim, atribuindo para cada processo, uma parcela da lista de números.

10

4.3.1 - Análise de Complexidade

A análise de complexidade do algoritmo paralelo levará em conta o limite superior nda lista de primos e número de processos p.

.

Tempo: a complexidade de tempo T(n) do Crivo de Eratóstenes paralelo no pior caso, melhor caso e caso médio é:

T(n) =O((n*log log n)/p)

Espaço: a complexidade de espaço E(n) do algoritmo paralelo no pior caso, melhor caso e caso médio é:

E(n)=O(n/p)

4.4 - Serial x Paralelo

A comparação dos resultados obtidos mostram que o tempo de execução do

Crivo de Eratóstenes de forma paralela se mostrou a alternativa mais escalável, apresentando um desempenho superior ao serial.

A utilização de algoritmos paralelos pode apresentar uma alternativa interessante para

a resolução de problemas de alto custo computacional. Caso o algoritmo paralelo seja

bem projetado, ele pode viabilizar soluções que não seriam possíveis utilizando apenas algoritmos sequenciais.

5 - Conclusão

Paralelismo é um dos grandes desafios da computação, que voltou a ganhar importância nos últimos anos com a abundância e barateamento de máquinas commodity permitindo a construção de clusters e o advento de GPGPU’s capazes de processamento paralelo em massa, permitindo que problemas cada vez maiores possam ser resolvidos eficientemente e com custo menor. No entanto, tanto arquiteturas de hardware como técnicas de programação tiveram de evoluir para acompanhar esse ganho massivo em paralelismo, pois técnicas automatizadas de paralelismo ainda estão longe de resolver todos os problemas existentes com desempenho aceitável, cabendo ao programador analisar cada situação. A programação paralela depende do entendimento do problema a ser resolvido, aliado à

uma estratégia de paralelismo restrita aos limites dos recursos disponíveis, e suporte em hardware.

REFERÊNCIAS

NOBRE, R. H. PARALELISMO COMO SOLUÇÃO PARA REDUÇÃO DE COMPLEXIDADE DE PROBLEMAS COMBINATORIAIS. Disponível em

<http://www.uece.br/mpcomp/index.php/arquivos/doc_download/265-dissertacao83-par

alelismo-como-solucao-para-reducao-de-complexidade-de-problemas-combinatoriais> Acesso em 07 de setembro de 2018.

ROCHA, R. FUNDAMENTOS DA COMPUTAÇÃO PARALELA. Disponível em <https://www.dcc.fc.up.pt/~ricroc/aulas/0607/cp/apontamentos/parteI.pdf> Acesso em 08 de setembro de 2018.

PAULO A. S. VELOSO. ANÁLISE DA COMPLEXIDADE DE ALGORITMOS

PARALELOS.

Disponível

em

<http://www.lbd.dcc.ufmg.br/colecoes/erad-rs/2002/004.pdf>

Acesso

em

10

de

setembro de 2018.

JÚNIOR, Fernando Antonio Fernandes; ZIVIANI, Nivio. Projeto e Análise de

em Acesso em 09

de setembro de 2018.

Algoritmos.

2006.

Disponível