Programação Paralela e por que você deveria se preocupar com isso (Parte 1)

Creio que a maioria dos desenvolvedores já deve ter ouvido falar de threads, aprendeu um pouco sobre semáforos, monitores e travas. Partindo desse meu pensamento, imagino que essa mesma maioria não utiliza nenhuma forma de programação paralela em suas aplicações. A pergunta que fica é: utilizar paralelismo e lidar com concorrência tem baixa popularidade entre os desenvolvedores porque não tem utilidade ou porque os cursos de graduação em computação estão carentes de uma disciplina que ensine aos graduandos os reais benefícios em ter uma base sólida nesta área?

Esta série de publicações irá trazer uma visão básica sobre Parallel Programming, os exemplos serão baseados em Java e muito do que mostro aqui pode ser encontrado de maneira mais aprofundada no livro "The Art of Multiprocessor Programming", dos autores Maurice Herlihy e Nir Shavit.

Sem mais blábláblá, é o seguinte: por que bexiga eu achei que deveria escrever sobre isso aqui no blog? Bom, o primeiro motivo é a importância que o assunto tem atualmente, embora tenha sido deixado de lado por muito desenvolvedor. O segundo motivo é que imaginei a dificuldade sentida por mim, para compreender programação paralela, em outros desenvolvedores, e acabei tentando passar de uma maneira mais fácil os conceitos e algumas dicas pra que o entendimento sobre eles seja mais fácil. Além disso, principalmente com a oportunidade que tive de aprender com um professor do CIn/UFPE, da área, que passei a respeitar muito, achei importante compartilhar o conhecimento, ou pelo menos tentar. O terceiro motivo merece um parágrafo em especial:

Por que se preocupar aprender Programação Paralela?

Pare e pense um pouco no mundo a sua volta, não precisa viajar, nem filosofar. Repare que ao seu redor várias coisas estão acontecendo em parelelo: uma luz acesa, seu celular te irritando te notificando com alguma atualização, você respirando (espero)... Tente modelar rapidamente uma aplicação para o ambiente que você está, ela conseguiria lidar com todos os eventos de forma sequencial?

Encare o mundo real brother.

A programação paralela é muito mais adequada para modelar, simular e entender fenômenos do mundo real. Por exemplo:
Trânsito
Mudanças climáticas
Monitoramento do Espaço Aéreo
Drive Thru

Pra que serve seu processador master-giga-quad-fuck-core?

Na teoria, utilizar mais recursos em uma tarefa irá reduzir seu tempo de realização, com potenciais economias em  capital (lembre-se que estamos na era da computação em nuvem e tarefas demoradas custam dinheiro). Além disso, alguns sistemas só fazem sentido (e funcionam) caso sejam utilizados vários recursos paralelos, um exemplo são os motores de busca e bancos de dados que processam milhões de informações por segundo. Imagine se você tivesse que esperar um motor de busca criado de forma sequencial? Teriam alguns milhões de usuários na sua frente, e você demoraria um pouco mais para achar aquela resposta salvadora no StackOverflow.

Os computadores atuais seguem uma arquitetura paralela, com múltiplos processadores/cores. Um sistema paralelo é voltado especificamente para hardware paralelo com múltiplos cores, threads e etc. Na maioria das vezes, programas seriais (como aquele sistema de cadastro de cliente que você fez mês passado) desperdiçam poder de computação.

Preocupe-se com o futuro, padawan.

Se olharmos para os últimos 20 anos, as redes cada vez mais rápidas, os sistemas distribuídos, e as arquiteturas multiprocessador (mesmo em desktops comuns) claramente mostram que o paralelismo é o futuro mais próximo da computação.

Neste mesmo período (segundo esse artigo aqui: "Overview of Recent Supercomputers", do A.J. van der Steen e Jack Dongarra) ocorreu um aumento de pelo menos 500,000x na performance de supercomputadores, sem um limite à vista atualmente.

Demonstração da evolução de performance
Se isso fosse uma corrida de Fórmula 1, atualmente os carros estariam na exascale km/h. No caso dos computadores isso quer dizer:
Exaflop = 1018 cálculos por segundo

Você não estará sozinho.

Historicamente, a computação paralela tem sido considerada o "alto nível da computação", e tem estado presente em muitas aplicações das Ciências e Engenharia:

  • Atmosfera, Terra, Ambiente;
  • Física - aplicada, nuclear, partículas, matéria condensada, pressão, fusão;
  • Biociência, biotecnologia, genética;
  • Química, Ciências Moleculares;
  • Geologia, Sismologia;
  • Engenharia Mecânica;
  • Engenharia Elétrica, Desenho de Circuitos, Microeletrônicos;
  • Ciência da Computação, Matemática, Economia
  • Defesa e armamentos.
Atualmente, a presença da computação paralela atingiu também a indústria e o comércio, com aplicações que exigem o processamento de quantidades de dados cada vez maiores, de maneiras sofisticadas. Por exemplo:

  • Banco de dados, Data Mining;
  • Motores de busca, serviços baseados na web;
  • Processamento de Imagens Médicas e diagnósticos;
  • Modelagem financeira e econômica;
  • Gráficos avançados e realidade aumentada;
  • Vídeos na rede e tecnologias multimídia;
  • Ambientes de trabalho colaborativo e Redes Sociais.
Os gráficos abaixos, obtidos no site Top500.org, mostram como a computação paralela está sendo utilizada em uma variedade de aplicações e quais os principais países que estão dominando esta área:

Variedade de áreas de aplicação da programação paralela.
Porcentagem de utilização de
computação paralela por país.
Segmentos das áreas onde a computação
paralela é aplicada.

Conhecer a história para entender nosso tempo.

Quem é de computação certamente já deve ter ouvido falar de John von Neumann (von Neumann inclusive era o nome de um servidor em um datacenter que estagiei na década passada, enfim, wtf?!). Em 1945, esse cara publicou um artigo (aqui: First Draft of a Report on the EDVAC), onde foi o primeiro autor a descrever os requisitos gerais para um computador eletrônico. Neste computador, também conhecido como "stored-program computer", instruções de programas e dados eram armazenados em uma memória eletrônica. Esta característica diferenciava o EDVAC de computadores anteriores, os quais era programados através de fiação rígida.

Desde então, virtualmente, todos os computadores tem seguido a lógica que von Neumann propôs lá em 1945:

  • Composto por quatro componentes principais:
    • Memória;
    • Unidade de Controle (Control Unit);
    • Unidade Lógica-Aritmética (Arithmetic Logic Unit);
    • Entrada/Saída (Input/Output).
  • Entrada/Saída, acesso randômico à memória utilizado para armazenar instruções de programas e dados:
    • Instruções de programas são dados codificados que "falam" para o computador realizar algo;
    • Dado é simplesmente a informação utilizada pelo programa.
  • A unidade de controle busca instruções/dados da memória, decodifica instruções e então sequencialmente coordena operações para completar a tarefa programada.
  • A unidade aritmética realiza operações aritméticas básicas.
  • A Entrada/Saída é a interface para o operador humano.
Mas quem se importa com isso? Então, sei lá, mas acontece que computadores paralelos atualmente ainda seguem este design, apenas multiplicando as unidades. A arquitetura básica e fundamental permanece a mesma.

Na próxima parte desta série irei mostrar os diferentes tipos de computadores paralelos, finalizando a introdução sobre os principais conceitos e terminologias utilizados até aqui.

Felipe Alencar

Felipe Alencar é doutorando em Ciência da Computação na UFPE, professor, desenvolvedor e acredita que só não virou jogador de futebol, surfista ou músico profissional por falta de tempo e talento.

Nenhum comentário:

Postar um comentário