Projeto: Avaliação de Desempenho

checklistParabéns! O seu programa de controle de produção de cachaça desenvolvido no projeto 2 foi um sucesso. Sua empresa foi comprada pela Companhia Paraibana de Aguardente por R$ 500 milhões! No entanto, como parte do processo de aquisição da empresa, um analista da CPA questionou a eficiência do algoritmo que você utilizou. A CPA re-escreveu o seu programa substituindo os múltiplos Atravessadores por um único Depósito Central que pode analisar todos os pedidos de cana de açúcar e atende-los de forma ótima.  A CPA testou quatro algoritmos diferentes mas não conseguiu decidir qual dos quatro é o melhor. Sendo assim, ela designou você e seu sócio como avaliadores do desempenho dos algoritmos e informou que o contrato de compra só será efetivado se vocês conseguirem apresentar um relatório com uma análise convincente sobre o desempenho dos algoritmos e indicando claramente a melhor opção dentre as disponíveis.

Material adicional para leitura:

O programa de gerenciamento de Produção de Cachaça

Você pode encontrar todos os arquivos da versão final do programa de gerenciamento de produção de cachaça no repositório de código fonte da disciplina. Copie todos os arquivos para a sua máquina e utilize os seguintes comandos para compilar o código fonte

 javac -Xlint:all *.java

e executar o programa

 java Projeto3 1 5 100

Examine os arquivos de código fonte. Você notará várias similaridades com o código do projeto 2 mas há algumas diferenças importantes. Ao invés de ter um Atravessador para cada variedade de cana açúcar tem apenas um Depósito Central que aceita pedidos de todos os Alambiques e controla como tais pedidos são processados. O Depósito Central possui seu próprio thread. Sempre que um novo pedido é enviado por um Alambique ou que uma nova carga é entregue pelo Fornecedor o método notify() é invocado para acordar o thread do Depósito Central. Os recursos são alocados de acordo com um dos quatro algoritmos disponíveis, selecionados por um argumento fornecido na linha de comando (o 1 no exemplo anterior). Você talvez precisa fazer pequenas alterações no código fonte para seus experimentos.

Os detalhes do programa são controlados por vários parâmetros de inicialização nos construtores das classes Alambique e Fornecedor. Você precisar experimentar diferentes valores para esses parâmetros. Você talvez precise também adicionar código fonte para obter estatísticas úteis sobre a execução dos quatro algoritmos.

O comportamento de um Alambique é controlado pelos parâmetros tempoDeEsperaMedio e requisicaoMaxima. O tempoDeEsperaMedio, como o próprio nome já indica, é o tempo médio (em mili-segundos) que um Alambique espera antes de fazer um pedido. O tempo exato é definido de forma aleatória mas segue uma distribuição exponencial com média tempoDeEsperaMedio (no jargão dos estatísticos isso é chamado de Processo de chegada de Poisson). O parâmetro requisicaoMaxima indica a quantidade máxima de cada variedade de cana de açúcar que pode ser solicitada pelo Alambique. O valor exato de cada quantidade g é definido de forma aleatória e distribuído de forma uniforme no intervalo [0, requisicaMaxima], fazendo com que um pedido especifique uma quantidade média requisicaoMaxima / 2 de cada variedade de cana de açúcar.

O comportamento do Fornecedor é controlado pelos parâmetros tempoDeEsperaMedio e fornecimentoMaximo. Como no caso dos Alambiques, o Fornecedor dorme por intervalos de tempo aleatórios e exponencialmente distribuídos e em seguida fornece a quantidade solicitada de cada variedade de cana de açúcar para o Depósito Central, até o limite fornecimentoMaximo para cada variedade.

O código fornecido tenta balancear as taxas de produção e de consumo dos recursos. Ou seja, o Fornecedor tenta gerar cana de açúcar na mesma taxa (média) em que o Alambique consome. Depois do número de iterações especificado no terceiro parâmetro da linha de comando, o Fornecedor é finalizado e o método main da classe Projeto3 finaliza o sistema interrompendo todos os threads dos Alambiques e o thread do Depósito Central, imprimindo em seguida uma série de estatísticas sobre a execução do programa.

Todos os números aleatórios são fornecidos por um único gerador, Projeto3.rand. Assim como no projeto 2, você pode passar o parâmetro -r na linha de comando para diminuir o nível de aleatoriedade.  Se você especificar esta opção, o gerador será sempre inicializado com a mesma semente. No entanto, haverá de qualquer forma algum nível de aleatoriedade na geração dos números, portanto, os resultados não serão necessariamente os mesmos em cada execução, mesmo com o parâmetro -r. Você pode escolher fazer alguns testes com a opção -r para entender o quanto as alterações nos resultados são causadas por flutuações aleatórias e quanto do resultado se deve as parâmetros e ao algoritmo.

Relatório

Inicialmente, analise os métodos DepositoCentral.algoritmo1()DepositoCentral.algoritmo2()DepositoCentral.algoritmo3()DepositoCentral.algoritmo4().

Infelizmente, os programadores da CPA não incluíram comentários descrevendo o funcionamento dos algoritmos.  O que cada algoritmo tenta fazer? Seriam eles análogos aos algoritmos de escalonamento de processos discutidos em sala de aula? Que tipo de comportamento devemos esperar de cada um desses algoritmos? Será que algum deles deveria ser “melhor” do que todos os outros? Talvez, um ou outro seja melhor dependendo do objetivo (tempo de resposta, quantidade total de recursos processados, justiça, etc). Talvez um ou outro algoritmo seja melhor dependendo das características da carga de trabalho (parâmetros dos Alambiques e do Fornecedor).

Projete experimentos para testar suas hipóteses. Analise cuidadosamente os resultados dos seus experimentos. Após uma análise inicial você pode concluir que mais experimentos são necessários para pode chegar a alguma conclusão.

Você deve encarar esta parte do projeto como encararia um experimento em um laboratório de física experimental. Utilize o método científico. Você deve formular hipóteses antes de iniciar os experimentos e utilizar os resultados dos experimentos para confirmar ou refutar suas hipóteses. Pense cuidadosamente sobre que parâmetros escolher para o programa. Execute algumas vezes o programa com várias combinações de parâmetros, imprima os resultados, leve para casa e reflita sobre o que ocorreu. Estes resultados preliminares devem ajuda-lo a escolher melhores parâmetros para uma segunda rodada de experimentos. Mas lembre-se, o que define a qualidade de um experimento não é a quantidade e sim a qualidade dos dados.

Se o programa não estiver imprimindo todos os dados que você gostaria, sinta-se a vontade para modifica-lo para imprimir o que você desejar. Você pode acabar concluindo que um pouco mais de informação pode ajudar a entender melhor o comportamento do programa.

Você deve preparar um relatório detalhado descrevendo os resultados obtidos. O relatório deve descrever detalhadamente os experimentos realizados e o que os resultados mostraram sobre os diferentes algoritmos utilizados. É preciso mostrar claramente a correlação entre os resultados obtidos e as conclusões alcançadas. Você precisa apresentar dados quantitativos que suportem as suas conclusões.

O texto do relatório não deve ter mais do que três páginas, sem contar gráficos, tabelas, etc.

Entrega

Você deve enviar o relatório (em formato PDF) e todo o código fonte utilizado nos experimentos para o meu e-mail na data especificada para a entrega.