Novo Blog

Novo endereço

https://blog.nilo.pro.br

sexta-feira, 3 de agosto de 2007

Multitarefa e Multiprocessamento

Leia no novo blog

Ao começar a escrever este post, lembro que julho foi um mês realmente atarefado, sem novos posts no JungleCoders. Mas foi um mês onde voltei a ler sobre as questões de hoje sobre multiprocessamento. Alguns anos atrás, havia menos processadores que usuários :-) Era a época dos computadores de grande porte ou mainframes.

Com a chegada do processador pessoal, iniciou-se a época do um para um, porém eram máquinas pequenas, com sistemas operacionais simples. Embora houvesse um processador por usuário, não havia sistema operacional, muito menos recursos no hardware, para suportar a troca de tarefas. Isso claro, para computadores pessoais, pois já existiam os super-micros e sistemas operacionais mais completos, como o Unix entre muitos outros. Com a evolução do Microsoft DOS e do próprio IBM PC, programadores começaram a se utilizar das interrupções de hardware para simular o multiprocessamento, eram os anos dos programas TSR (Terminate and Stay Resident). Quem nunca usou programas como Norton Guides ou Sidekick? Mas os mais populares eram os tais reloginhos que ficam no canto superior da tela. Todo programador DOS tinha que implementar um... Ok, o Mingo pode dizer que o Amiga já tinha multitarefa de verdade, mas poucos felizardos tiveram acesso a estes sistemas.

Para salvar a linhagem do IBM PC, surgiu o Intel 80286. Mas o pobre DOS continuava monotarefa, exceto pelos TSRs... A IBM lançou o OS/2 e renovou as esperanças de um sistema multitarefa para pobres mortais. Para empresas, o Novell Netware e variantes de Unix já existiam. Com a chegada do Intel 80386 a coisa ficou realmente séria e o Windows 3.0 começou a convencer que a multimídia seria o futuro. O novo sistema permitia que vários aplicativos rodassem ao mesmo tempo, mas não podiam ser mal comportados. Se uma tarefa resolvesse tomar conta do sistema operacional para si... descobríamos que se tratava de multitarefa cooperativa... era o fim. Novas versões do OS/2 surgiram com um novo termo, a tal multitarefa preemptiva. Com a preemptividade, o sistema operacional podia recobrar o controle da máquina, mesmo que uma das tarefas não contribuísse muito para isso.

Bom, o OS/2 nunca pegou realmente para usuários domésticos, sendo relegado a pequenos feudos corporativos e segundo lendas urbanas sobrevivendo até hoje em bancos. O Windows 95 trouxe a preemptividade para os sistemas da Microsoft e para nós, pobres usuários. O grande problema é que às vezes o sistema operacional travava... deixa isso pro passado :-) O sistema foi se estabilizando e agora temos outros tipos de problema. Máquinas domésticas passaram a ter 2 ou 4 processadores e sistemas como Windows XP e Linux têm dado conta da tarefa de utilizar os recursos destas máquinas, mas com uma restrição: se a aplicação é desenvolvida com um só thread, esta não pode ser distribuída para mais de um processador :-( Pode parecer pouca coisa, mas se você não tomar cuidado por ter a aplicação rodando mais lentamente numa máquina com dois processadores.

A grande questão hoje é como escrever programas para este novo mundo? Agora temos vários processadores para nossas aplicações, porem programar com threads ainda é muito difícil. Algumas pessoas acreditam que há necessidade de mudarmos a forma que programamos hoje. Outros acreditam em compiladores inteligentes, capazes de decidir que partes do código podem ou não ser executadas em paralelo. Apesar de não parecer grande problema, a Intel sinalizou que já possui processadores com 80 núcleos no laboratório. Imagine um dia ter uma máquina dessas e ter seu pobre programa rodando a apenas 1/80 do poder total da máquina :-) ?

Como nada é aceito por todos ao mesmo tempo, já existem várias abordagens para este problema. Uma delas é utilizar outras linguagens de programação, com paradigmas diferentes como Erlang ou Haskell. Meu pobre Python está longe disso. Segundo o Guido, a solução é utilizar vários processos e morar na casa mal assombrada dos IPC (Inter-process Communication). Pelo pouco que sei, Ruby anda pior ainda neste quesito. Java, C/C++/C# (*.net) estão bem, mas toda a dor de múltiplos threads fica para o programador.

Uma luz vem do mundo dos jogos, pois os processadores gráficos das placas de vídeo possuem mais de 30 pipelines. Rodando a mais de 500 MHz, estes processadores ficam sem uso quando não estamos jogando, um poder de processamento desperdiçado. Tanto a NVidia quanto a ATI prometeram publicar os compiladores para suas GPUs, mas já avisaram que a forma de programar é diferente.

Quem já trabalhou com IPC e threads sabe que o pode ser feito, mas não de graça. Como os softwares tem se tornado cada vez mais complexos, como resolveremos a questão de criar softwares capazes de aproveitar os recursos de multiprocessamento de nossas máquinas? Eu particularmente acredito na utilização de linguagens com novos paradigmas que propiciam a abstração dos threads, mas no fundo desejo que algo de novo surja na área de compiladores e que todos nós possamos continuar a programar como sempre programamos. Como nem só os computadores são multitarefas, eu resolvi acrescentar o estudo deste tipo de problemas a minha já enorme lista :-) Talvez eu troque meu sistema operacional...