sábado, 19 de fevereiro de 2011

Demolindo um computador com uma linha!


Estamos sempre falando sobre a evolução do hardware e a evolução do software. Tudo leva a crer que o ritmo de desenvolvimento do software não tem sido suficiente, ou seja, os desenvolvedores não são tão caprichosos atualmente como poderiam. Isso me fez lembrar um episódio muito interessante que aconteceu há anos atrás que ajuda a ilustrar este ponto de vista de forma surpreendente.

No começinho de década de 90 eu trabalhava na Proceda, uma empresa que era “bureau” de serviços de informática do grupo Bunge Y Born e que também vendia serviços de processamento de dados baseado em mainframe para outras empresas do mercado. A Proceda tinha uma área de processamento de contas de fundo de garantia, usando programas que já vinham sendo usados desde a década de 60!!! Nessa época a empresa tinha um mainframe que era o “supra-sumo” da época, um IBM 3090 com 6 módulos processadores atendendo cerca de 6000 terminais (locais e remotos). Na ocasião só a Petrobrás e Embraer tinham mainframes mais potentes no Brasil. Além disso havia um ambiente de desenvolvimento, totalmente separado usando um ambiente muito mais modesto, embora ainda muito custoso. Tudo no mundo dos mainframes custa milhões de dólares!
(foto ilustrativa-IBM 3090 modelo mais simples)

Definido o cenário, preciso explicar o que fazia eu nesse contexto. Eu me desenvolvi desde o começo de minha carreira profissional na área de microcomputadores. Mas como tinha desenvolvido um projeto de comunicação micro-mainframe eu tive um ponto de intersecção com este outro mundo da informática. Como os custos relacionados a mainframe são muito altos, a empresa apostou em um projeto que eu tive a felicidade de iniciar, que era a implantação de um ambiente de desenvolvimento para mainframe baseado em rede local de microcomputadores. Havia uma simulação de CICS, CMS, IMS e tantas outras engenhocas de mainframe de forma a baratear e agilizar os custos de operação. Para vocês terem uma idéia, os programadores da época economizavam compilações de programa, pois sabiam que usavam preciosos ciclos de CPU a cada rodada. Se o programa funcionava o custo de fazer os testes, mesmo no ambiente de desenvolvimento (no mainframe) eram também elevados. Por isso fazia total sentido trazer para a rede de PCs o trabalho de desenvolvimento. Compilações e testes ilimitados a custo zero ou quase zero se comparado com o mesmo trabalho feito no mainframe.

Isso define bem o que fazia eu neste processo. Voltando ao assunto, existia um tal processamento de contas de fundo de garantia que era muito pesado. Toda vez que entrava consumia cerca de 0,25% de CPU do sistema. Não se esqueça que era uma HIPER máquina com 6 módulos de processamento só pior que o mainframe das duas estatais citadas anteriormente. Um belo dia a Proceda herdou de um outro bureau o processamento das contas de fundo de garantia do extinto banco Comind, que falira há alguns anos. Outros lotes de processamento de outras origens eram muito mais pesadas e já era tratadas pelo tal programa. Iria ser fácil engolir mais esses milhares de contas.

Para surpresa geral, na primeira vez que as novas contas foram agregadas para o processamento (vários milhares frente quase um milhão que já eram processadas) a CPU “entrou em parafuso”!!! Quase 40% de uso uma CPU gigante como aquela era assombroso!!! Afinal o que acontecera???
A área de análise e programação não conseguia descobrir. Eles estavam muito céticos frente àquela rede local ser utilizada para desenvolvimento. Falando em bom português eu sentia que apesar deles virem a ter um grande aumento na qualidade de seu trabalho no ambiente da rede local, eles se sentiam sendo “diminuídos” deixando de usar aqueles terminais 3270 ligados à “mamãe IBM”.

Nessa hora eles de forma muito “perspicaz” (para não dizer sacana), falaram que se aquela engenhoca era tão boa, nós seríamos capazes de achar o problema. Ou seja, como não conseguiram resolver o assunto, passaram a “batata quente” para frente. Se desse certo o trabalho teria seria feito em benefício deles. Se desse errado serviria de pretexto para falar mal da solução. Situação ingrata fomos colocados.

O que eles não sabiam que “apesar” de rodar em microcomputador, aquela solução já dispunha de recursos inimagináveis para os desenvolvedores de mainframe. Só para citar dois recursos, os famosos “breakpoint” e “profiler” foram suficientes para achar o problema. O profiler é um recurso que “mapea” o consumo de recursos por trechos do programa. Conseguimos uma massa de testes de 1% do tamanho original, suficiente para investigar o nefasto fenômeno. Localizado o trecho “vilão”, usamos o recurso de breakpoint para fazer interromper o programa e executar passo a passo olhando o código fonte do programa. Arrisco-me a dizer que nem hoje, quase 15 anos depois, existem estes recursos para desenvolvimento em mainframe. Indo direto ao ponto, achamos o problema, a despeito da torcida contra. Vou explicar o que aconteceu.

O programa original, feito em 1965, e alterado por uma ou duas dezenas de pessoas ao longo do tempo, previa uma tabela para processamento de lançamentos de exceções. Esta tabela era relativamente pequena, com alguns poucos milhares de registros. Em uma manutenção feita em 1976 um brilhante programador resolveu acessar os dados dessa tabela em uma outra ordem e por isso incluiu um comando de ordenação dessa tabela. Até aí nada de mais, certo? Quase. Ele na pressa de fazer o seu trabalho incluiu UMA ÚNICA LINHA NO PROGRAMA, este comando de ordenação, dentro de um loop de processamento principal. Assim a cada registro processado essa tabela auxiliar era novamente ordenada. Apesar desse erro conceitual a catástrofe ainda não tinha sido estabelecida, pois como disse essa tabela auxiliar era pequena. Quando a Proceda herdou o processamento do finado Comind, no processo de migração de dados por algum motivo obscuro, alguém decidiu “para separar bem as coisas”, usar a tal tabela de lançamentos de exceções para este fim. Esta tabela subiu de 5 mil registros para 125 milhões de um dia para outro!!!! Imagine essa tabela imensa sendo ordenada cerca de 200 milhões de vezes. Achado o “absurdo”, deslocamos o comando de ordenação para ser executado fora do loop principal.

Para resumir o final da história o programa original teve feita a mudança recomendada pela minha equipe e de o uso do mainframe caiu 40%, para 0,12% apenas por esta simples mudança!!! Menos que o consumo de CPU pré Comind. Mas nada valeu mais a pena que ver a expressão incrédula da equipe que era responsável por este sistema, que tinham certeza que não conseguiríamos, ao ver o resultado da empreitada.

Alguns meses depois eu saí da empresa e soube que motivos políticos fizeram inviabilizar aquele belo projeto. Como não estava mais lá, não cabe a mim julgar se a decisão foi certa ou errada. A experiência foi muito rica e a lição aprendida foi grande. Mas em sua opinião o problema foi causado por um problema de projeto ou mau uso do sistema?


PS : este texto foi originalmente publicado por mim na sessão de colunas no site FORUMPCs com o título "E a base de dados cresceu!!"

2 comentários:

  1. O problema com toda certeza foi causado pela combinação de ambas causas.
    Problema de projeto, ao ser herdado um programa com uma sub rotina que embora funcionasse para uma determinada especificação de projeto, não foi analisada no contexto geral, quando inclusa e acionada pelo mau uso do sistema.
    Um programa funciona ótimamente bem, quando todos os seus processos são sempre verificados.
    É algo ingrato sim, mas hoje em dia, depende muito da empresa que faz isso e dos profissionais envolvidos.
    Nem todos abraçam a causa ou vestem a camisa e peitam de frente o problema.

    ResponderExcluir
  2. Oi Silvio, sua análise é precisa, exata!! Super obrigado por suas observações e comentários!! Abraços

    ResponderExcluir