Tornado e Grand Central Dispatch: uma olhada rápida

Tornado and Grand Central Dispatch: a quick look
Autor original: Nathan Willis
Publicado originalmente no:
lwn.net
Tradução: Roberto Bechtlufft

Duas empresas tradicionalmente proprietárias lançaram produtos como código aberto recentemente: o Facebook lançou um framework de aplicativos/servidor web baseado em Python chamado Tornado, e a Apple lançou um sistema de gerenciamento de pools de threads chamado Grand Central Dispatch. Não é a primeira vez que essas empresas lançam código aberto, mas vale a pena examinar os dois projetos. O Tornado foi desenvolvido para atender a tipos específicos de aplicativos web, e dizem que ele é muito rápido, enquanto o Grand Central Dispatch pode fazer alguns desenvolvedores repensarem o paralelismo de tarefas.

O Tornado

O Tornado é, na verdade, um produto do FriendFeed, o agregador de redes sociais adquirido pelo Facebook em agosto. Ele consiste de um servidor web e de um framework em volta dele (todo escrito em Python), especializado em lidar com quantidades muito grandes de conexões abertas e estabelecidas. O componente de servidor web (tornado.web) é “não bloqueador” – ou seja, é conduzido por eventos, tendo sido desenvolvido em torno do recurso epoll do kernel do Linux, e por isso pode manter um grande número de soquetes TCP abertos sem consumir memória excessiva e sem um número grande de threads.

Servidores web conduzidos por eventos, como o Tornado, são de thread única; cada thread tem potencial para gerenciar milhares de conexões abertas, desde que o aplicativo não bloqueie enquanto espera pelos dados do soquete – a thread simplesmente as sonda, uma de cada vez. Mais conexões podem ser gerenciadas executando múltiplos processos do servidor em sistemas SMP. Por outro lado, os servidores web tradicionais sofrem bloqueio ao tentar lidar com conexões adicionais enquanto aguardam por E/S, ou precisam invocar threads adicionais para lidar com conexões adicionais, ao custo de alternância de contexto e maior uso de memória.

Além do servidor web em si, o Tornado inclui um pacote de módulos usados para construir aplicativos web, incluindo decodificação de XHTML, JSON e URL, um wrapper para bancos de dados MySQL, um módulo de localização e tradução, um mecanismo de modelos em Python, um cliente HTTP e um mecanismo de autenticação, sendo que este último tem suporte a esquemas de terceiros, como OAuth e OpenID, e esquemas para sites específicos, como Facebook, Yahoo e Twitter.

O código do Tornado é hospedado no GitHub, e está disponível sob a licença Apache 2.0. Ele funciona com Python 2.5 e 2.6, e precisa do PycURL e de uma biblioteca JSON funcional. A documentação está disponível em tornadoweb.org, e um aplicativo de bate-papo está funcionando como demonstração em http://chan.friendfeed.com:8888/.

Bret Taylor, do FriendFeed, anunciou o lançamento em seu blog, comparando o Tornado ao web.py e ao webapp do Google. Ele afirma que nos testes de comparação de desempenho do Apache, o Tornado conseguiu lidar com um número quatro vezes maior de solicitações por segundo (ou mais) do que frameworks concorrentes, incluindo o web.py, o Django e o CherryPy.

O post de Taylor e o debate que ele provocou geraram alguma controvérsia entre os usuários e os desenvolvedores do framework Twisted, que se opuseram aos comentários depreciativos feitos em relação à maturidade e a adequabilidade do código do Twisted. O fundador do Twisted, Glyph Lefkowitz, postou uma longa resposta às afirmações feitas sobre seu projeto, mas de modo geral aprovou o lançamento do Tornado em si. Matt Heitzenroder postou seus próprios testes comparativos de desempenho, que mostram que o Tornado supera o Twisted.web, mas não por uma margem ampla.

À parte dos resultados, muitos na comunidade de código aberto pareceram impressionados com o que o Tornado oferece: um framework simples para a construção de aplicativos web de “sondagens longas“, incluindo suporte à criação de modelos, gerenciamento de cookies, localização e tudo o que estiver no meio disso, em um único pacote. Como o Tornado já se provou viável como o framework por trás do FriendFeed, é provável que conquiste uma quantidade significativa de adeptos como um projeto de código aberto.

Threads invisíveis

O Grand Central Dispatch (GCD) da Apple é um recurso em nível de sistema operacional que estreou no recém-lançado OS X 10.6 (“Snow Leopard”). O GCD é basicamente um mecanismo que permite aos desenvolvedores de aplicativos paralelizar seu código, mas que deixa o sistema operacional se preocupar com o gerenciamento inteligente das threads. O GCD determina o número máximo de threads simultâneas no sistema e gerencia as filas de todos os aplicativos em execução. Sendo assim, o desenvolvedor de aplicativos só precisa escrever código compatível com o GCD, e confiar no sistema operacional para tirar o máximo proveito dos núcleos e processadores múltiplos.

O lançamento do código fonte da Apple consiste na biblioteca da API de espaço de usuário (libdispatch) sob a licença Apache e nas alterações realizadas no kernel XNU, o kernel de código aberto da Apple, baseado no Mach e comum ao OS X e ao Darwin. As alterações no XNU supostamente aumentam o desempenho da interface de notificação de eventos Kqueue. Mas o GCD também depende de uma extensão não padrão ao C, ao C++ e ao Objective-C, os “blocos” (blocks), ou seja, o suporte aos blocos no compilador é um pré-requisito para os desenvolvedores de aplicativos que queiram tirar proveito do GCD. Há suporte aos blocos no compilador LLVM, através do projeto compiler-rt.

Como o GCD abstrai a criação de threads do desenvolvedor de aplicativos, ele se assemelha mais ao OpenMP ou ao TBB da Intel. Os três permitem que o desenvolvedor determine partes do código como “tarefas” a serem paralelizadas de alguma forma. A diferença do GCD é que ele faz uso de um recurso da linguagem (os blocos) em vez das diretivas de pré-processador do OpenMP ou dos modelos do TBB. Além disso, o TBB está limitado ao C++, mas o OpenMP está disponível para C, C++ e Fortran.

Os blocos são basicamente funções anônimas definidas internamente. Eles são designados por um circunflexo (^) no lugar de um nome de função, aceitam argumentos como qualquer função, e podem retornar um valor. A diferença é que os blocos possuem acesso somente leitura às variáveis de seu escopo-pai (recurso semelhante aos “fechamentos” em linguagens como o Ruby). Consequentemente, ao substituir um loop for pelo equivalente paralelo do GCD, o dispatch_apply, o desenvolvedor pode escrever um bloco com o conteúdo do loop sem o incômodo de ter que passar argumentos extras para ele só para ter acesso às variáveis que estavam disponíveis no loop.

No documento Concurrency Programming Guide da Apple, temos o seguinte loop de exemplo:

for (i = 0; i < count; i++) {
printf(“%un”,i);
}

que poderia ser expresso como um bloco pronto para o GCD desta forma:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(count, queue, ^(size_t i) {
printf(“%un”,i);
});

Quando executado, o GCD cria um número de tarefas igual a count, uma para cada iteração do bloco, pondo-as em uma fila de tarefas. O GCD disponibiliza uma fila padrão com a dispatch_get_global_queue(), mas os desenvolvedores podem criar filas particulares se quiserem; para serializar o acesso a uma estrutura de dados compartilhada, por exemplo. No tradicional exemplo de paralelização de um loop for, as tarefas são enfileiradas de forma assíncrona, mas o GCD oferece vários mecanismos para o monitoramento da conclusão das tarefas, como callbacks e semáforos.

A Apple disponibiliza uma introdução básica ao GCD e à programação com blocos em seu site para desenvolvedores. Além disso, a comunidade de pesquisa científica do OS X em MacResearch.org tem um tutorial detalhado, com exemplos para o GCD e o código equivalente escrito para o OpenMP. O MacResearch.org postou números de desempenho básico para seu código-tutorial, e a Apple postou um comparativo entre o GCD e o código serializado e as threads POSIX nativas.

Até o momento, o GCD só foi implementado para o Mac OS X, mas a reação da comunidade de desenvolvedores tem sido positiva. Deixar os detalhes do gerenciamento do pool de threads por conta do sistema operacional parece ser uma ideia vitoriosa; a maior parte da discussão nos fóruns do Mac se focou na sabedoria de apoiar-se em um extensão de linguagem, como é o caso dos blocos. O Ars Technica comentou sobre as áreas nas quais o Linux poderia se beneficiar de uma implementação nativa do GCD, como em frameworks de níveis mais altos como QtConcurrent, mas observa que o uso da licença Apache limita a integração a projetos usando a GPL 3 ou mais recente.

Impacto

A Apple e o Facebook tem um histórico de lançamentos regulares de projetos de código sob termos de código aberto, ainda que as duas empresas tenham a reputação de manter seus jardins de produtos básicos cercados por muros de proteção. Como é de se imaginar quando grandes empresas proprietárias lançam código aberto, uma energia considerável foi gasta na web especulando-se acerca do que cada empresa espera “ganhar” com os lançamentos. Uma das teorias mais populares sobre o GCD é a de que a Apple espera aumentar a adoção dos blocos no C e no C++ padrões, mas ainda não há consenso sobre o motivo do lançamento do Tornado.

Na verdade, nem o Tornado nem o GCD causaram muito impacto na comunidade de código aberto, mas se a reação inicial for um bom indicativo, ambos são produtos sólidos e valiosos. Dos dois, é mais provável que o GCD inflame debates apaixonados, já que assimilá-lo completamente ao Linux exigiria mudanças em dois pilares fundamentais da comunidade: no kernel e no compilador. Embora o LLVM tenha seus fãs, a comunidade Linux ainda é predominantemente um ecossistema GCC. A inclusão de código da Apple no kernel do Linux e no GCC é algo que não vai acontecer tão facilmente.

Créditos a Nathan Willis – lwn.net
Tradução por Roberto Bechtlufft <info at bechtranslations.com.br>

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X