Author Archive

Bizarro… mas muito útil!

O artigo do Miguel sobre perólas do mundo Java me fez lembrar de um trecho de código com o qual me deparei há um tempo atrás que me parecia também muito bizarro… até eu sacar um pouco depois a imensa utilidade dele!

O código, em linguagem C, era algo como o seguinte:

do {
  __alguma_coisa;
} while (false);

Em princípio fazer uma construção de laço para executar algo apenas uma vez parece algo bem bizarro, não?! Diria que é quase um primo-irmão do if (liberado==true). Foi exatamente o que eu achei. Mas colocando esta construção dentro do contexto em que eu a achei eu consegui ver (depois de alguma pesquisa, é claro) que ela é extremamente útil em alguns casos.

A primeira vez que eu me deparei com esta construção eu estava analisando o código-fonte do GNUChess, um jogo de xadrez de código livre. Como eu sei que o pessoal que escreve código livre algumas vezes utiliza umas construções bem diferentes do que normalmente estamos acostumados, resolvi investigar o porquê deles estarem utilizando esta construção. Afinal de contas, se este código é livre e várias pessoas já devem tê-lo revisado, não havia motivo para um laço aparentemente tão inútil estar lá sem alguma utilidade verdadeira, não é mesmo?!

E foi só pesquisar um pouco sobre o assunto para enteder melhor o que estava acontecendo. As construções como a acima só apareciam em definições de macros. Nunca em código “normal”. Para quem talvez não tenha muita familiaridade com macros em C, elas são basicamente códigos que você define e que serão literalmente expandidos pelo compilador onde seu identificador aparecer no código. Ou seja, um código assim:

#define macro_exemplo printf("Macro de exemplo!\n");
int main(void) {
  macro_exemplo
  return 0;
}

seria entendido pelo compilador, após o processamento das macros, da seguinte forma:

int main(void) {
  printf("Macro de exemplo!\n");
  return 0;
}

Ou seja, o preprocessador de código do compilador substitui a referência à macro_exemplo pela sua definição literal. No caso do nosso código bizarro, teríamos que definir a macro da seguinte forma:

#define macro_exemplo2 do { __alguma_coisa; } while (false);

ou ainda:

#define macro_exemplo3 do { \
                         __alguma_coisa; \
                       } while (false);

Note que uma macro deve ser definida sem quebras de linhas ou com quebras de linhas sinalizadas pelo caracter de escape barra invertida (’\').

Mas, ainda assim, não haveria motivo para o laço na minha macro, certo? Bom, se você pensar na macro como um código por si só, talvez isto esteja certo, mas não podemos esquecer que este código será copiado literalmente para algum outro lugar sempre que o identificador da macro for referenciado pelo programa. E muitas vezes não queremos fazer macros simples como as que eu mostrei no meu exemplo. Por exemplo, podemos querer fazer algo mais complexo como o seguinte:

#define IMPRIME_ESPACOS(n) for (int j = 0; j < n; j++) printf(" ");
#define ROTULO(rot) printf("L%d:", rot); do { int n = numeroDigitos(rot); IMPRIME_ESPACOS(6 - (n + 2)) } while (false);

A macro IMPRIME_ESPACOS(n) imprime uma quantidade de espaços em branco representadas pelo “argumento” n. Estou usando argumento entre aspas porque o argumento de uma macro em C se comporta de maneira diferente de um argumento de função, já que não há checagem de tipo e sim uma simples substituição do valor passado como argumento da macro nas suas referências dentro da própria macro. Já a macro ROTULO(rot) recebe como “argumento” um rótulo e imprime Lrot seguido de um numero de espaços de tal forma que todas as linhas que chamarem a macro ROTULO(rot) estarão identadas na mesma posição (desde que o rótulo tenha menos de 6 caracteres, que era o limite utilizado no programa a partir do qual tirei o código de exemplo).

Alguém certamente já bateu o olho no código acima e deve ter dito: poxa, eu poderia chamar a função
numeroDigitos(rot) dentro de IMPRIME_ESPACOS na definição da macro ROTULO. Não podemos nos esquecer no entanto que macros não são chamadas de função e que onde se lê IMPRIME_ESPACOS em ROTULO dever-se-ia ler na verdade a definição de IMPRIME_ESPACOS. Neste caso, se passássemos uma chamada de numeroDigitos como “argumento” de IMPRIME_ESPACOS, a função numeroDigitos seria chamada dentro do loop definido em IMPRIME_ESPACOS sempre que a condição de parada do loop fosse ser calculada. Ou seja, teríamos um número excessivo e desnecessário de chamadas a numeroDigitos. Para solucionar este eventual problema, decidi criar uma variavel para armazenar o valor da chamada de numeroDigitos e passar esta variavel como argumento para IMPRIME_ESPACOS. O problema é que dependendo de onde este código for ser substituído pode não ser permitido ter declarações de variáveis.

Neste último caso (e em muitos outros), o código mostrado no início deste post, por mais bizarro que possa parecer a primeira vista, pode ser a solução, pois o uso do do { ... } while (false); torna possível a criação de um contexto local dentro das chaves do falso loop na macro. Dentro deste contexto é possível criar-se quantas variáveis se queira ou, por exemplo, encadear comandos dentro de uma macro que não ficarão perdidos se esta macro for utilizada dentro de um if-else.

Ah, e se alguém ficou curioso, procure na Internet: vocês verão muitos outros usos do do-while (false). Sinceramente, muitos deles, na minha opinião são dispensáveis e só servem para complicar código que poderia ser escrito de outra forma. E, pra falar a verdade, a única construção que eu já achei em códigos livres foi esta que eu cito aqui, dentro de macros. É preciso ter dicernimento na hora de usar este tipo de construção. Aliás, para falar a verdade, mesmo este caso que eu descrevi aqui, que eu acho interessante e útil eu só usária em últimos casos em códigos profissionais.

E agora Android?

Eu estava quase passando despercebido por uma notícia da semana retrasada. Parecia até uma notícia não muito relevante, mas pensando bem, achei que valia a pena comentar, já que este foi um assunto já discutido antes aqui neste blog.

Fiquei sabendo pelo blog do Doug Schaefer, principal mantenedor do CDT, que a Nokia tinha adquirido controle total sobre a Symbian. Em princípio a notícia não é muito impactante porque a Nokia já era uma das principais acionistas da Symbian. E era obvio que a Nokia tinha interesse direto no Symbian, que é um dos sistemas operacionais muito usados em SmartPhones. So far, so good.

Mas, como está no anúncio da Nokia, o propósito não é apenas controlar a Symbian. O objetivo final é abrir o código-fonte do Symbian OS sob licença EPL (Eclipse Public License), criando a Symbian Foundation. Com isto, a Nokia, que é a maior fabricante de celulares e de plataformas móveis atualmente, faz frente ao anúncio do Android feito pelo Google e da Open Handset Alliance o ano passado.

O mais interessante, no entanto, é observar o que vai acontecer daqui para a frente. O Android, até onde eu sei, é apenas a descrição de um padrão. Ele pode ter várias implementações. E apesar de a Nokia não fazer parte da Open Handset Alliance, muitas das outras empresas que junto com ela estão promovendo a abertura do código do Symbian fazem. Para a Nokia, como detentora do posto de líder de mercado, o importante era fazer um movimento dizendo que ela não está a revelia dos últimos acontecimentos em relação à criação de padrões abertos no mercado de celulares. Resta saber o que ela e seus parceiros no Symbian OS vao querer fazer com o Symbian OS de código-aberto: continuar com ele  sendo algo separado do Android ou torná-lo um sistema compatível com o padrão da Open Handset Alliance.

Software Livre e inovação

Tem uma coisa que o Raphael vira e mexe fala que me dá arrepios: “FOSS não funciona como estímulo para a inovação”. A última vez que eu me lembro que ele falou isso foi aqui. E pelo jeito não sou o único que tem estes arrepios como se pode ver pelo comentário do Carlos Costa neste mesmo post do Raphael.

E eu não sinto arrepios porque sou um defensor inveterado do software livre. Na verdade eu acho que existem coisas boas tanto do lado do software livre como do lado do software proprietário e acho que tem espaço para todo mundo. Sinto arrepios porque realmente acho que software livre tem muita inovação de verdade. O problema é que eu ainda não consegui achar um contra-exemplo cabal para você, Raphael. Pelo menos não para o sentido de inovação que eu acho que você quer dar à sua frase. :)

De certa forma eu concordo parcialmente que os conceitos implementados em software livre já foram testados no mercado. Isso é verdade muitas vezes. Mas eu acho que este ponto de vista é limitado. No fundo eu acho que os conceitos implementados em software livres são maduros o suficiente, tendo sido ou não implementados pelo mercado. Isto porque quando você se envolve em uma comunidade de pessoas, em geral a tendência é aceitar apenas coisas que já estejam maduras o suficiente e que portanto, irão muito provavelmente gerar código de qualidade.

Não me entendam mal: não acho que software livre não tenha inovação por completo. Se olharmos de perto o GCC, ou o Eclipse ou vários outros projetos open source veremos que eles tem sim uma grande dose de inovação. Mas eu diria que, na visão macro, eles são mais inovadores na forma de fazerem coisas que já existem do que na forma de criarem coisas novas. O que não impede, é claro, que muitos testes e invenções estejam sendo feitas na visão micro destes softwares. Eu diria que eles são mais parecidos com o que a Apple anda fazendo nos últimos anos(copiando conceitos já existentes e dando uma roupagem diferente a eles, inventando uma coisinha aqui e outra ali) do que com o que a Intel ou a IBM fazem no campo de processadores por exemplo (efetivamente pesquisando novas tecnologias e tentando aplicá-las no mundo real).

Aonde eu quero chegar com isso? Para mim o principal problema na frase do Raphael é o mal uso da palavra inovação.

O que é inovação? Quando eu vejo alguma coisa como “FOSS não funciona como estímulo à inovação” eu interpreto mais como “FOSS não funciona como estímulo para a invenção”. Até pouco tempo atrás eu achava muito sútil e muitas vezes inexistente a diferença entre invenção e inovação. Mas a cada dia eu venho me atentando mais para a diferença entre estas palavras. Invenção é realmente inventar coisas novas, fazer algo que nunca foi feito antes. Inovar não é necessariamente inventar: inovar é muitas vezes pegar algo que já existe e, com uma roupagem nova, criar algo que tenha um apelo ou uma utilidade ainda maior do que aquilo que existia antes. Ainda que eu não goste muito da frase, como diria Jean Paul Jacob, “Inovação é o enlace entre invenção e a visão do valor desta invenção”. É exatamente isto que a Apple anda fazendo muito bem nos últimos anos: efetivamente não inventando nada de novo, mas habilmente dando um novo valor e uma nova visão a produtos que já existiam.

Sob esta ótica eu acho que software livre é extremamente inovador. Inovador no modelo de desenvolvimento. Inovador nas idéias implementadas. E, algumas vezes, inovador ao inventar novas coisas e novos conceitos também. Como eu disse antes, ainda não achei um exemplo cabal de um produto completo de software livre que seja totalmente novo (e talvez aí esteja a falha na minha argumentação contra a frase do Raphael… alguém pode me ajudar?). E acho até que isto é apenas um reflexo da economia de mercado: se você inventou algo que acha bom, porque não ganhar dinheiro com isso? Software livre é muito usado em partes já comoditizadas de sistemas (o que não exclui inovação) e a parte de maior valor agregado tende a ser proprietária justamente para gerar mais lucro. Mesmo assim eu poderia citar diversas funcionalidades que foram implementadas antes em software livre (algumas até mesmo no projeto em que eu trabalho) e que nunca tinham sido feitas antes por nenhum outro software. Quer um exemplo? Suporte em sistema operacional, compiladores e debuggers a plataformas híbridas: processadores que possuem núcleos de diferenças arquiteturas no mesmo chip. Isso é totalmente novo. E apareceu primeiro em plataformas de código aberto. Se isto não é inovação, o que é então?

ICANN libera criação de domínios de topo

A ICANN (Internet Corporatoin for Assigned Names and Numbers) deciciu recentemente levar a cabo uma idéia que vinha sendo estudada e maturada desde o fim da década passada: liberar o registro de domínios de topo na Internet.

Para quem não conhece, a ICANN, junto com a IANA (Internet Assigned Numbers Authority), são as entidades mundiais responsáveis por definir as regras de distribuição de números IP e registro de nomes na Internet. São eles por exemplo que definem que os endereços registrados no Brasil devem terminar em .br ou que endereços registrados  nos EUA podem terminar apenas em .com ou .edu sem ter um .us depois. Ou seja, eles são responsáveis pelo controle da última parte dos nomes de domínios da Internet: aquilo que vem depois do último ponto.

Esta última parte do domínio é conhecia como gTLD (generic top-level domain). Hoje existem relativamente poucos gTLDs oficialmente suportados. Com a proposta que eles aprovaram virtualmente qualquer pessoa ou empresa poderá registrar seu próprio gTLD. Por exemplo a IBM poderá registrar o .ibm. e assim seu site principal poderá responder apenas por “ibm” ou invés de “ibm.com” como é hoje. Se eu fosse uma pessoa muito egocêntrica (e rica) eu poderia registrar o .laggarcia e mudar meus esparsos posts neste blog para blog.laggarcia.

É claro que o registro não vai ser um processo fácil nem barato. Vi estimativas na Internet variando de US$ 50K a US$ 400K. Além disso eles impuseram uma série de regras para que não seja criado um mercado de gTLDs: ou seja, qualquer um registra o gTLD .ibm e depois tenta fazer a IBM pagar uma bagatela para ceder a ela o direito de uso deste gTLD.

Outra decisão interessante que eles tomaram foi liberar endereços com caracteres em chinês, árabe e outras línguas que não usam um alfabeto latino. Mas acho que isso pouco deve afetar a maior parte dos brasileiros que acessam a Internet…

Todas estas mudanças devem gerar, é claro, um grande impacto na escalabilidade do sistema. Todos as buscas por gTLDs na Internet toda são processados por não mais que duas dezenas de servidores. Não sou um especialista em redes, mas imagino que estas buscas não são tão constantes hoje em dia porque estes valores são bem fixos, mas tornando a coisa mais flexível o sistema também sofrerá uma sobrecarga muito provavelmente. Ai está outro ponto interessante: parece que eles também querem que haja competição entre as empresas que fornecem este tipo de serviço de resolução de gTLDs.

Minha primeira impressão disso tudo foi: que bagunça! Mas, pensando melhor, até que eu acho que a idéia não é tão ruim no sentido que ela vai ampliar o alcance da Internet, já que os endereços passarão a ser, em alguns casos, mais naturais para pessoas não sistemáticas como em geral computeiros são, além de estimular a competição entre os provedores deste tipo de serviço. Já com relação aos problemas técnicos, não saberia dizer quão complicado isso poderia ser, mas imagino que estas autoridades já devem ter pensado neste problema também (caso contrário o sistema de DNS entraria em colapso, o que seria sentido por todos que usam a Internet).

Cryptology ePrint Archive

Complementando um post do Alexandre sobre OpenSouce na Ciência tem um outro site muito interessante que disponibiliza artigos sobre criptografia que ainda não foram eventualmente aceitos em nenhum congresso: o Cryptology ePrint Archive.

A idéia é parecida com a que foi citada pelo Alexandre: hoje pode ser muito difícil ter acesso ao conhecimento científico publicado em revistas e congressos. Além disso em alguns campos do conhecimento como é o caso da criptografia existe um outro agravante: é necessário publicar idéias o mais rápido possível para evitar que outros a patenteiem antes. E, para completar, o site ainda funciona como um crivo não-oficial para idéias novas, isto porque não existem muitos requisitos para publicar no site: ou seja, se você tem uma idéia mas não sabe se ela é boa o suficiente você pode publicá-la (correndo é claro o risco de compartilhar sua idéia com outros antes de ela estar completa) e ver o retorno que a comunidade dá em relação a ela. Se for bom, com o tempo esta idéia pode amadurecer e virar um artigo em um congresso internacional.

O interessante é ver que na área de criptografia muitas coisas interessantes são publicadas no ePrint. Tem inclusive cientistas bons que estão defendendo abertamente a idéia de se publicar o conhecimento sem restrições sempre, como é o caso de Daniel Bernstein.

Já ouvi falar que existem portais parecidos para artigos em Física, além dos já citados pelo Alexandre. Enfim, um movimento muito interessante, que de certa forma força os pesquisadores a se importar mais com a qualidade e menos com a quantidade, já que seu artigo é “mais público” neste tipo de site. Algo que vai um pouco contra a “ditadura” de números que regem muitos institutos de pesquisa no mundo atualmente, onde é melhor quem publica mais e não necessariamente quem obtém melhores resultados.

P.S.: Editor-chefe, eu disse que eu postava algo este mês ainda! :)

Coisas que você deveria saber a respeito da sua empresa

Este post não é especificamente relacionado à computação, mas acho que todo bom computeiro que trabalhe em uma corporação (seja ela pequena ou grande) deveria ter noção das coisas citadas no livro “Corporate Confidential — 50 Secrets Your Company Doesn’t Want You To Know and What To Do About Them” (Editora St. Martin’s Griffin) da autora Cynthia Shapiro.

Não li o livro, mas o resumo apresentado aqui e aqui pela revista Você S/A já são interessantes o suficiente para atiçar minha curiosidade de ler a descrição mais completa apresentada no livro.

Já me vi em várias das situações descritas e tendi a concordar com os pontos apresentados na maior parte delas. Vale a pena dar uma olhada!

Ainda sobre o MacBook Air

Antes de mais nada tenho que dizer que não acompanho os lançamentos da Apple com muita atenção. Nada contra a Apple em si, mas acabo acompanhando outras coisas que me interssam mais. Mas parece que o maior lançamento deles feito na maior conferência sobre produtos da Apple este ano foi o MacBook Air.

Por fora, como a maior parte das coisas da Apple, o design é muito interessante. Mas confesso que não dou tanta bola pra assim para o design. É claro que gosto de ter coisas bonitas, mas prefiro ter coisas boas antes de ter coisas bonitas. E foi por isso que minha primeira impressão do MacBook Air não foi das melhores. O fato de ele não ter CD/DVD interno me deixou atônito.

Mas ai, pensando um pouco mais, quantas vezes eu uso meu drive de CD/DVD? Poucas… Então porque eu tenho um? Bom, ele de vez em quando é útil, eu diria. E já me salvou algumas vezes.

Mas pensando mais ainda, há muitos anos atrás a Apple foi a primeira fabricante que eu tenho notícia que parou de lançar computadores com drives de disquetes. E, como sabemos hoje, este foi um caminho certo. Eu não tenho drive de disquete há 4 anos. E acho que posso contar nos dedos de uma mão quantas vezes ele me fez falta. E nenhuma dessas vezes eu não consegui outra solução sem usar um disquete.

Seguindo o mesmo raciocínio, talvez as unidades de CD/DVD também estejam com os dias contados. Pelo menos em computadores portatéis.

Commodore SX-64 versus MacBook Air

Commodore SX-64 versus MacBook Air

Miguel, não resisti…

Portal Cell BE Brasil

Semana passada entrou no ar um portal pelo qual eu vinha batalhando há algum tempo: o Cell BE Brasil.

Para quem talvez ainda não saiba, durante os últimos dois anos boa parte do meu trabalho foi focado no desenvolvimento de aplicativos básicos para a plataforma de processadores Cell Broadband Engine, que equipam, entre outros, o PlayStation 3 da Sony. Especificamente no meu caso, trabalhei com o desenvolvimento de plug-ins para o Eclipse que adicionam funcionalidades a esta plataforma de desenvolvimento para tornar a vida de um programador desenvolvendo em C/C++ para processadores Cell BE mais fácil.

Junto com este trabalho veio também uma série de palestras e aulas sobre a arquitetura Cell BE por todo o Brasil. Hoje o Brasil é, provavelmente, o único país da América Latina em que existe uma comunidade acadêmica e científica aproveitando o alto poder de processamento fornecido pelo Cell BE em pesquisas.

Esta divulgação toda e a verdadeira comunidade que se formou no Brasil em torno desta nova plataforma de processadores trouxe novas necessidades de comunicação. E é para suprir esta necessidade que colocamos no ar o portal Cell BE Brasil.

O objetivo deste site é servir como um centro para discussões e postagem de material e artigos sobre a tecnologia Cell BE em português. Junto com ele foram criados também um fórum de discussão e um Wiki, todos em português. Além disso, a partir do portal já se tem acesso hoje a alguns outros sites e portais com bom material relativo a esta plataforma de desenvolvimento (muitos deles ainda só em inglês). Enfim, a idéia é agregar!

Se você tem interesse ou usa esta plataforma de desenvolvimento, entre e participe! Ajude-nos a fortalecer ainda mais a comunidade de Cell BE no Brasil.

Otimização fina de código

Há um tempo atrás num post polêmico do Miguel (ando falando demais no passado né? mas tem coisas que não dá pra deixar passar…) o Raphael escreveu um comentário que me incomodou:

Performance? Dane-se! Python é mais lento que Java? Sem dúvida. Mas performance pura não importa hoje em dia. Hardware hoje já é tão barato que pouco importa se eu tenho que ter 1, 2 ou 3 máquinas para rodar o sistema. O que não pode é ter uma plataforma tão lenta que me obrigue a comprar 20 ou 30, que seria o caso do Ruby. Questão de ordem de grandeza.

É claro que eu tenho plena conciência que o Raphael não acredita 100% na afirmação acima e que ele estava envolvido numa discussão (quase) sem sentido com o Bruno… :P Prova disso é que mais pra frente, em outro comentário ele escreveu:

Eu quero uma stack de protocolo de comunicação SIP que atenda 100 mil usuários simultâneos

Que vai exatamente contra o que ele tinha dito antes! Afinal de contas, neste exemplo desempenho é primordial ou nada funciona. Talvez por isso eu estivesse achando a discussão (quase) sem sentido… Mas… vamos ao que (me) interessa!

O fato é que desempenho importa sim em muitos casos. Em algumas áreas ele é, eu diria, primordial. Mais essencial até que uma boa interface homem computador. Duvida? Pense então em criptografia.

Quase todo mundo hoje em dia sabe o que é criptografia e quase ninguém duvida que ela é essencial para nossa (falsa?) segurança na Internet. O fato que pouca gente sabe é que ainda hoje algoritmos criptográficos são exageradamente pesados. Aliás, para o desespero de alguns, é exatamente aí que está o segredo: não existe, ainda hoje, nenhuma prova formal de que algoritmos criptográficos sejam realmente seguros. O que todo mundo sabe é que é muito difícil quebrá-los com o que se conhece de teoria matemática hoje em dia. E é nessa dificuldade que é baseada boa parte da segurança das comunicações mundiais. Parece frágil isso, não? Definitivamente! E olha que eu nem comecei a falar nas técnicas não-matemáticas para se quebrar um algoritmo criptográfico… Mas isso não é conversa para este post.

Neste post, antes que eu perca o fio da meada de novo, quero falar de desempenho! Como algoritmos criptográficos ainda hoje são muito pesados, é muito comum você achar artigos e artigos na Internet de autores se vangloriando por terem achado um novo método revolucionário de implementar um algoritmo criptográfico que traz um ganho de desempenho de incríveis 5%! Ou ainda pesquisadores gastando meses fazendo testes para descobrir a combinação de flags de otimização a serem usadas no gcc para fornecer um ganho de 3%!

E é ai que eu queria chegar. Estudando um pouco sobre criptografia este semestre eu aprendi com o professor Julio López da Unicamp um método de otimização de código capaz de fazer com que um código rode consideravelmente mais rápido. Pense no seguinte trecho de código, bastante comum em algoritmos criptográficos:

if (a & 0x80)
r ^= b;

Basicamente o que se deseja fazer é testar um bit da variável a. Se este bit for 1 faz-se uma operação de soma em aritmética módulo 2 (um XOR) da variável b sobre um acumulador da resposta r. Este tipo de código, apesar de simples, costuma ser executado de forma muito ineficiente em processadores de propósito geral modernos. Isso porque este processadores são muito rápidos mas não são adivinhos. Para simplificar bastante o assunto, podemos dizer que antes de eles terem idéia do resultado do if eles já estão tentando executar a instrução em seguida (a soma). No entanto, eles podem descobrir alguns ciclos de relógio depois que a soma não deveria ser executada pois o if deu falso. Neste caso eles tem que voltar atrás e desfazer o deslocamento.

Os processadores modernos até tentam adivinhar qual caminho é o certo, mas nem sempre isso dá certo. Descobrir que o que ele estava fazendo estava errado e voltar atrás é algo que penaliza muito o processador. Perde-se às vezes dezenas de ciclos de relógio com isso… Tempo suficiente para executar talvez de 6 a 10 instruções, dependendo do processador. Ou seja, se conseguíssemos eliminar este if do código poderíamos ter um ganho. O código para eliminar o if acima é o seguinte:

r ^= b & (-((a & 0x80) >> 7));

Alguém vai dizer: “Ora bolas, mas agora ao invés de um if, que é em geral uma comparação e um salto condicional, e um XOR eu estou fazendo um XOR, dois AND, um deslocamento e uma inversão de sinal!” Por incrível que pareça isso, muitas vezes, é mais rapido, pois elimina qualquer possibilidade do processador ter que voltar atrás e jogar fora processamento, perdendo dezenas de ciclos de relógio de execução.

É este tipo de truque de programação que muitos pesquisados da área de criptografia passam meses tentando descobrir. Este truque, aliás, é bem conhecido. Ele é muitos outros podem ser vistos no livro Hacker’s Delight. Nunca olhei o livro profundamente mas ele já me foi muito bem recomendado.

E você tem algum truque bacana destes pra nos ensinar?

Usando Regexp

Há menos de um mês atrás o Miguel escreveu um post muito interessante sobre regexp. Como ele disse lá, expressões regulares são uma das ferramentas que devem fazer parte da caixinha de maldades de qualquer desenvolvedor. Concordo plenamente. O uso de expressões regulares não só deixa o código menor como mais inteligível também.

A única coisa que acho que faltou no post anterior foi um exemplo que mostrasse estas vantagens nuas e cruas. E por isso vou colocar aqui um exemplo real extraído do CDT, o C/C++ Development Toolkit do Eclipse. Dentre as inúmeras necessidades de interpretação de conteúdos de String que o CDT precisa uma delas é especial: o CDT precisa interpretar a saída do compilador para poder “entender” os eventuais erros de compilação e mostrá-los na interface gráfica. No caso dos comandos de compilação executados pelo GCC isso é tratado pela classe org.eclipse.cdt.internal.errorparsers.GCCErrorParser. Tirando alguns detalhes da arquitetura interna do CDT que mudaram da versão 3.0 para a 4.0, se olharmos o código desta classe dá pra ver nitidamente várias coisas interessantes.

Versão 3.0

Versão 4.0

Quem deu uma olhada nos links acima pode ver que a primeira coisa que se nota é que a classe que usa regexp tem 65 linhas enquanto a versão anterior possui 298! É claro que ouveram outras alterações na arquitetura dos ErrorParsers do CDT entre as versões, mas a maior diferença se deve à mudança no paradigma de programação. Isso porque se olharmos bem a classe da versão 3.0 é possível ver que ela usa métodos da classe String para agilizar o trabalho de parsing. Se ao invês disso fosse usado o processamento byte a byte da String ela seria muito maior!

O uso de expressões regulares neste caso não só deixa o código menor mas também muito mais fácil de ser lido. É bem mais fácil entender o que é feito na classe da versão 4.0 do que na classe da versão 3.0. É claro que a eficiência de um mecanismo de interpretação de expressões regulares deve ser um pouco menor que um parsing direto da String. No entanto é importante lembrar de duas coisas neste caso: 1) pouco provavelmente você conseguirá desenvolver parsers do zero que sejam tão otimizados quanto as rotinas de regexp disponíveis e 2) manutenibilidade do código é tão primordial quanto eficiência e, no caso de mecanismos de parser, facilidade de leitura do código e entendimento é mais primordial ainda já que um código obfuscado pode simplesmente esconder o que o desenvolvedor queria fazer.

Turing completeness (Pra que linguagens de programação?)

Pessoal, primeiro queria me desculpar por minha ausência neste blog nos últimos tempos… Infelizmente eu acho que eu sou o colaborador mais esparso por aqui e não tenho grandes perspectivas de melhorar minha taxa :-/ De qualquer forma, como o Miguel ainda não me expulsou, continuo na ativa para a felicidade (ou não) dos dois leitores deste blog (não fossem os comentários de outras pessoas e as estatísticas do blog eu chegaria a acreditar piamente que só o Raphael e o Bruno lêem este blog nos últimos tempos… obrigado pela participação de todos!). :)
Como todos devem saber, o Raphael e o Bruno vêm há algum tempo em uma discussão (às vezes) quase religiosa com dezenas de comentários sobre o artigo “Viva a diversidade!” do Miguel. Muita gente deve estar cheia de ler os comentários deles! Eu, inclusive, já passei por uma fase assim, mas acabei lendo todos os comentários em batch depois. Acho que é isto que levou o Miguel a “censurar” (será?) os dois. :) De qualquer forma, acho que este blog deve ser um meio livre de expressão. Se eles querem se matar discutindo um assunto que, a meu ver, não tem muito sentido, deixa eles lá.

De certa forma, discussões grandes como esta acabam gerando ligações com assunto muitas vezes nada a ver com a discussão principal. E foi exatamente isso que me chamou a atenção neste comentário do Raphael. Mais especificamente, a seguinte parte me chamou a atenção: “Em última análise, TODAS as linguagens são possíveis de se fazer QUALQUER tipo de construção lógica. Se não fosse assim, elas não seriam Turing-Complete, tampouco mereceriam o nome “Linguagem de Programação”.”

Isso me lembrou de um fato que eu aprendi há muito tempo e que é uma daquelas coisas que não mudam sua vida porque provavelmente você nunca mais vai ter que lembrar dele no seu dia-a-dia mas fazem com que tudo faça sentido (se um dia você estiver buscando a essência das coisas, como eu acho que o Raphael estava quando ele escreveu esta frase).

Turing completeness é um conceito que, na verdade, estrapola linguagens de programação. Qualquer máquina abstrata ou linguagem de programação que seja capaz de executar qualquer tarefa computacional é classificada como turing complete.

Quando você desce o nível, das linguagens de programação de alto nível para as coisas mais essenciais, como assembly e linguagem de máquina, você vai descobrir que ser turing complete nada mais é do que ser capaz de executar pouco mais de meia dúzia de instruções. Descendo mais o nível, veríamos que para projetar um circuito lógico capaz de executar todo este conjunto de instruções você precisaria de apenas um tipo de portas lógicas: ou só NANDs ou só NORs. Você não vai precisar de mais que dois transistores para fazer cada uma destas portas lógicas. Duvida? Aqui e aqui.

Desta forma, eu acho que toda esta discussão sobre qual linguagem de programação é melhor realmente é inócua. Parodiando o célebre post de Linux Torvalds, homens de verdade precisam apenas de máquinas turing complete. Nada mais!

E é por isso que eu conclamo todos vocês a largarem toda esta porcariada de frameworks, modelos de programação, orientação à objeto, programação funcional, lambdas e o escambal e passemos todos a projetar tudo que precisamos fazer em termos de NANDs (por um gosto pessoal eu prefiro o NAND ao NOR, mas, para não parecer inflexível, acho que podemos liberar o NOR também). Caso alguém realmente precise de algo de mais alto nível, são permitidos os instructions set mínimos ou, já que eu sou uma pessoa benevolente, o uso da linguagem Whitespace, que, segundo o artigo sobre instruction set mínimo, chega perto de algo minimalista (mas não deixa de ser uma linguagem de alto nível, na minha opinião, então use com parcimônia). Coisas como Path language nem pensar. Elas não são suficientemente minimalistas, por mais que a home page dela te faça pensar o contrário.

Com estas tecnologias (e apenas com elas!) acho que daqui há uns 200 anos conseguiremos chegar num nível tecnológico suficiente para termos blogs funcionando novamente. Quem sabe assim eu não ganho tempo suficiente para pensar no meu próximo artigo… :)
Nota: Antes que alguém me acuse de reacionário: esta é uma obra de ficção. Qualquer relação dela com seu autor ou com qualquer outra pessoa é azar deles.

Reactable no Brasil

Caros,

Em março eu escrevi este artigo aqui sobre o Reactable, um sintetizador pós-moderno (até que o moderno se torne antigo).

Reactable
Foto: Martin Kaltenbrunner

Para quem quiser ver um destes em ação, a edição do FILE 2007 - Festival Internacional de Linguagem Eletrônica, no SESI de São Paulo - SP, de 14 de agosto a 9 de setembro, vai ter demonstração do uso deste sintetizador com os músicos da banda da contora Björk.

Nunca vi um de perto, mas acho que vale a pena conferir esta e outras atrações do FILE 2007!

Folding@HOME e PS3 (ou “Os vídeo-games e a inovação na computação - parte 3″)

Andei meio distante deste blog nos últimos três meses por diversos motivos mas voltando a escrever, queria falar de um mesmo assunto sobre o qual eu estava falando da última vez que eu escrevi aqui: Os vídeo-games e a inovação na computação. Para quem tiver interesse em ler os dois primeiros artigos sobre este assunto eles estão aqui e aqui.

Desta vez queria falar sobre como todo o poder de processamento dos novos vídeo-games podem ser usados para… não rodar jogos! Mas, se não formos rodar jogos em vídeo-games, o que faremos com eles?

Bom, como disse no primeiro artigo sobre este assunto, pelo menos dois dos vídeo-games desta nova geração, o PlayStation 3 e o XBox 360, na minha opinião, tem como objetivos se tornarem as centrais de entertenimento da casa, gerenciando conteúdo e conectando todos os dispositivos multimídia de uma casa. Mas além disso, pelo menos o PlayStation 3, já nasceu como um computador completo. Desde que foi lançado era possível conectar um teclado e um mouse a ele, rodar Linux e, com isso, usá-lo como um desktop. Vá lá que não é um desktop lá grandes coisas porque a pouco memória (só 256 MB) e o mal uso do processador Cell pela maior parte dos aplicativos do sistema operacional, que utilizam apenas um dos nove núcleos dele, tornam a experiência não muito boa.

No entanto, se bem usados todos os núcleos do processador Cell eles podem entregar até 200 GFlops, o que é muito se comparado com os cerca de 15 GFlops de um Athlon 64, por exemplo. No caso do processador Cell, as aplicações que tiram maior proveito deste poder de processamento são aquelas que possuem grande parte do seu trabalho concentrado em processamento matemático pesado e intenso.

E daí? E daí que se as aplicações forem bem escritas, podem usufruir de todo este poder de processamento e se tornarem muito poderosas. Um bom exemplo disso são as aplicações do BOINC. Para quem não conhece o BOINC, ele é um projeto criado pela Berkeley University. BOINC significa “Berkeley Open Infrastrucutre for Network Computing”. Ou seja, é basicamente um projeto que cria aplicações clientes para diversas plataformas que utilizam o tempo de processamento ocioso em computadores distribuídos em rede (na Internet, por exemplo) para processar coisas que um computador sozinho levaria milhares de anos para processar, mesmo que ele fosse bem poderoso. A rede criada pelo BOINC já possui diversas aplicações e uma das mais antigas e populares é o Folding@Home. O Folding@HOME utiliza a infra-estrutura do BOINC para fazer cálculos poderosos sobre como átomos e moléculas se juntam para formar proteínas. A formação de proteínas é um processo complexo e a forma espacial das moléculas de proteínas é importantíssima na função que elas exercem nos organismos vivos. O Folding@Home realiza cálculos para tentar entender como se dá o processo de empacotamento e desempacotamento das moléculas de proteínas e qual é a influência destes processos no desenvolvimento de doenças. Para quem quiser saber mais sobre o BOINC e o Folding@Home, pode ver aqui e aqui.

As aplicações do BOINC são um exemplo prático de aplicações que necessitam de grande poder de processamento. E, pensando nisso, o pessoal do Folding@Home ficou de olho grande no poder de processamento do processador Cell presente no PlayStation 3 e desenvolveu um cliente específico para esta plataforma para utilizar o poder de processamento ocioso dos vídeo-games! Ou seja, se você não estiver jogando, vai poder ajudar pesquisas importantes para o avanço da humanidade. Para se ter uma idéia da “ajudinha” que os PlayStation 3 estão dando para o Folding@Home, eles representam cerca de 10% dos processadores sendo utilizados de forma distribuída por esta aplicação, mas, por outro lado, entregam mais da metade do poder de processamento atual! Para maiores informações sobre isso, basta clicar aqui. Uma ajuda e tanto vindo de vídeo-games! Quem poderia imaginar algo assim há algum tempo atrás?

O ponto importante disso tudo é que o nível de convergência que estamos vivendo atualmente das várias tecnologias e mídias de distribuição de conteúdo estão fazendo com que coisas antes centradas apenas em entertenimento, como vídeo-games, já estão sendo pensadas hoje também como componentes centrais de sistemas distribuídos em todo o mundo. E, como vimos, não estou falando de jogos online.

Wii (ou “Os vídeo-games e a inovação na computação - parte 2″)

Continuando a falar um pouco sobre vídeo-games e o impacto que eles causam na evolução da computação (meu primeiro post sobre este assunto você encontra aqui) eu vou falar um pouco do Wii, o vídeo-game de sétima geração da Nintendo.

Wii

Olhando por fora, o Wii parece bonito. Mas todos os vídeo-games de sétima geração investiram bastante na sua imagem externa. O melhor mesmo está naquilo que os olhos não vêem (pelo menos em um primeiro momento).

Por um lado tem os processadores do Wii. O processador central é um IBM Broadway, um processador basedo em PowerPC. Como eu disse no primeiro artigo desta série, não é à toa que todos os vídeo-games de sétima geração possuem processadores IBM: eles tiram proveito da robustez das tecnologias desenvolvidas nos últimos anos pela IBM para a família de processadores Power para o mercado de processadores de servidores, que exigem uma alta carga de trabalho. Além disso o Wii vem com um processador gráfico da ATI, o ATI Holywood. Isso por si só coloca este vídeo-game com capacidade de processamento para torná-lo um representante da nova geração de vídeo-games.

É claro que, apesar do aumento do poder de processamento em relaçao ao GameCube, o vídeo-game de sexta geração da Nintendo, este, digamos assim, não é o grande diferencial deste console. Em relação aos outros consoles de sétima geração, o XBox 360 da Microsoft e o PlayStation3 da Sony, o Wii nem é assim tão poderoso em relação à sua capacidade de processamento. Apesar de existirem muito poucas informações oficiais a respeito do IBM Broadway, certamente ele possui uma arquitetura bem mais simples que a dos processadores multi-core presentes no XBox 360 e no PlayStation 3.

O Wii também tem todas aquelas coisas que os vídeo-games de sétima geração trazem: suporte a Wi-fi, Bluetooth, USB, adaptadores para redes locais, leitura de mídias óticas, etc. Além disso, ele também é compatível com os jogos do GameCube e consegue se conectar por rede sem fio com o Nintendo DS, o atual console de mão da Nintendo. Mas tudo isso, apesar de muito legal, também não é o que faz do Wii único.

O grande diferencial do Wii, para mim, é a forma pela qual os usuários interagem com os jogos e outros eventuais programas rodando no console. O nome inicial do projeto do Wii era “Revolution e, apesar da mudança do nome no laçamento do console, a forma de interação com o Wii é realmente revolucionária.

A Nintendo desenvolveu um controle sem fio, o Wii Remote. Até ai nada demais. Só que este controle é dotado da capacidade de perceber a sua posição, a direção em que ele é apontado e a velocidade em que se movimento no espaço, ou seja, ele possui um acelerômetro dentro dele. Desta forma, o Wii permite que o usuário interaja com os programas na tela através do movimento e da direção do controle.

Isto torna possível, por exemplo, que uma pessoa jogando um jogo de tênis para o Wii não fique apenas apertando os botões para que o seu “hominho” no jogo vá de um lado para o outro da tela e aperte um outro botão para “acionar” a raquete do “hominho”. Agora é possível realmente jogar tênis, se posicionando na frente da tela e, com o Wii remote, fazendo o seu “hominho” ir para um lado ou outro da quadra quando você se movimenta com o controle na frente da tela e fazendo com que o “hominho” rebata a bola quando você fizer o movimento certo com sua raquete virtual, representada pelo Wii remote, na frente da tela. Imaginem quantas novas possibilidade não podem se abrir a partir desta forma revolucionária de interação com os computadores?

Além disso, o Wii remote é expansível, o que permite a conexão de outros controles ao controle principal. Por exemplo, existe uma extensão, chamada de Nunchuk, que é parecida com um manche de avião e possui os velhos botões direcionais dos controles de arcade. Ele também possui um acelerômetro e você pode usar um Nunchuk em uma mão e um Wii Remote em outra durante um jogo! Além disso você pode conectar controles de alguns vídeo-games anteriores ao Wii Remote e jogar seus jogos do GameCube com o mesmo controle, ou, em outras palavras, com a mesma interface que você estava acostumado.

Toda esta realidade adicional, obviamente, empolga os jogadores. Não é à toa que a Nintendo está fazendo recall dos Wii Remote para subsitutir a presilha que vem com o controle para segurá-la junto ao punho do jogador: a presilha não foi feita forte o suficiente para suportar a força que está sendo imprimida por alguns jogadores no controle e os Wii Remote estão literalmente voando das mãos em alguns casos!

Esta nova forma de interação está fazendo com que o Wii, anunciado no final do ano passado, perto do lançamento do PlayStation 3, da Sony, esteja sendo mais popular e mais vendido que seu rival em muitos lugares, mesmo sendo o PlayStation 3 o vídeo-game mais aguardado dos últimos anos.

Esta nova forma de interação também pode abrir novos caminhos para a computação e para a forma como interagimos com as máquinas hoje em dia. Pode inspirar muitos sistemas no futuro. Sejam eles jogos ou não.

Next Page »