Documentos de Académico
Documentos de Profesional
Documentos de Cultura
INSTITUTO DE INFORMTICA
CURSO DE CINCIA DA COMPUTAO
SUMRIO
LISTA DE FIGURAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RESUMO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ABSTRACT
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
INTRODUO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
MOTIVAO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
3 FUNCIONAMENTO DA APLICAO . . . . . . .
3.1
Aplicao de Transferncia Eletrnica de Fundos
3.1.1
Checkout . . . . . . . . . . . . . . . . . . . . . .
3.1.2
Conversor Client . . . . . . . . . . . . . . . . .
3.1.3
TEF Dedicado . . . . . . . . . . . . . . . . . . .
3.1.4
Rede Autorizadora . . . . . . . . . . . . . . . .
3.1.5
Topologia da Aplicao . . . . . . . . . . . . . .
3.1.6
Motivos da Paralelizao . . . . . . . . . . . . .
3.1.7
Fluxo Transacional da Aplicao . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
11
11
11
12
12
12
12
13
13
4 FUNDAMENTAO TERICA . . . . . . . . . . . . . . . . . . . . . .
4.1
Programao Paralela em Outros Trabalhos . . . . . . . . . . . . . . . .
4.2
Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1
Gerenciamento de Threads . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.2
Sincronizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3
Problemas convertendo Cdigo Monothread em Cdigo Multithread . .
4.4
POSIX Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.1
Criao e Juno de Threads com a Biblioteca Pthreads . . . . . . . . . .
4.4.2
Sincronizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
15
15
15
16
17
18
18
18
19
19
20
21
21
22
24
.
.
.
.
.
.
.
. . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
5.3.4
Anlise e Modificaes da Biblioteca conexaotcp.dll . .
5.3.5
Anlise e Modificao da Classe CPrintDeb . . . . . . .
5.3.6
Anlise e Modificao da Classe CFilaEventos . . . . . .
5.3.7
Anlise e Modificao das DLLs das Redes Autorizadoras
5.3.8
Anlise e Modificao da Classe CEncriptaAes . . . . .
5.3.9
Aplicativo para Testes do Paralelismo . . . . . . . . . .
5.4
Anlise da Implementao . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
24
26
29
30
31
33
34
. . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
35
35
35
50
CONSIDERAES FINAIS . . . . . . . . . . . . . . . . . . . . . . . .
52
REFERNCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
6 RESULTADOS OBTIDOS . . . . .
6.1
Ambiente e Metodologia de Testes
6.2
Testes e Resultados . . . . . . . . .
6.3
Concluso sobre o captulo . . . .
7
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
POS
Point of Sale
TEF
PTHREADS
Posix Threads
GPRS
Wi-Fi
Wireless Fidelity
POSIX
IEEE
VCL
TCP
LAN
TPS
DLL
API
SPC
PDV
Ponto de Venda
ATM
RENPAC
CPU
HD
Hard Disk
BIN
LISTA DE FIGURAS
Figura 3.1:
Figura 3.2:
Topologia da Aplicao . . . . . . . . . . . . . . . . . . . . . . . .
Fluxo Transacional . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
14
Figura 5.1:
Figura 5.2:
Figura 5.3:
Figura 5.4:
Figura 5.5:
Figura 5.6:
Figura 5.7:
Figura 5.8:
Figura 5.9:
Arquitetura da Aplicao . . . . . . . . . . .
Copiando Arquivos . . . . . . . . . . . . . .
Adicionando Biblioteca ao Projeto . . . . . .
Adicionando Biblioteca ao Projeto . . . . . .
Configurando Projeto para uso da Biblioteca
Configurando Projeto para uso da Biblioteca
Threads x VCL . . . . . . . . . . . . . . . .
DLL ConexoTCP . . . . . . . . . . . . . .
Benchmark POS . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
20
22
22
23
23
23
24
25
34
Figura 6.1:
Figura 6.2:
Figura 6.3:
Figura 6.4:
Figura 6.5:
Figura 6.6:
Figura 6.7:
Figura 6.8:
Figura 6.9:
Figura 6.10:
Figura 6.11:
Figura 6.12:
Figura 6.13:
Figura 6.14:
Figura 6.15:
Figura 6.16:
Figura 6.17:
36
37
37
38
39
40
40
41
42
43
43
44
45
46
46
47
Figura 6.18:
Figura 6.19:
Figura 6.20:
Figura 6.21:
Figura 6.22:
Figura 6.23:
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
48
48
49
49
50
50
51
RESUMO
ABSTRACT
INTRODUO
Computadores com processadores multicore so mais comuns nos dias de hoje, por
isso um ganho de desempenho de uma mquina est mais vinculado ao nmero de cores
do que ao clock desse processador.
Entretanto, no adianta termos mquinas multicore se as aplicaes executam apenas
em uma thread. O intuito de criarmos aplicaes multithreads, ou seja, paralelizarmos
as aplicaes, para que essas possam usufruir dos vrios ncleos dos processadores,
buscando assim um melhor desempenho na execuo das suas atividades.
O aplicativo em questo trata da Tranferncia Eletrnica de Fundos (TEF), que
um servio que permite aos clientes efetuarem pagamentos a estabelecimentos comerciais atravs de transaes realizadas com instituies financeiras, utilizando-se de cartes
magnticos. Esse sistema trabalha de forma sequencial, ou seja, os dados recebidos so
armazenados em uma lista e processados um aps o outro, fazendo com que a aplicao,
conforme a quantidade de transaes, no aproveite o potencial das mquinas atuais, j
que o cdigo da aplicao serial.
O objetivo desse trabalho paralelizar uma aplicao com a API Posix Threads, objetivando uma melhor performance executando-a em mquinas multicore.
10
MOTIVAO
Verificou-se em uma empresa da rea da informtica que muitas de suas aplicaes poderiam ter uma melhora no seu cdigo, o que contribuiria para um melhor aproveitamento
do hardware atual. Em um dos sistemas dessa empresa, no h vantagem na utilizao de
mquinas multicores, devido ao cdigo fonte das aplicaes ser escrito com programao
sequencial. Foi analisado que, para alguns clientes, em dias de grande volume de dados, o
processamento de uma CPU ficava comprometido, alcanando quase 100% de uso. Para
tratar esse volume de transaes, seria necessrio a duplicao do hardware e do sistema.
Isso acarreta em uma descentralizao dos dados, ou seja, as informaes para pesquisas,
como relatrios, arquivos de manunteno, entre outros, estaro em mquinas diferentes,
o que prejudica a captao desses dados. Alm disso, tambm necessrio um balanceamento das transaes que chegam na primeira ou na segunda mquina, o que uma tarefa
dispendiosa.
Com base nesses dados, este trabalho prope a paralelizao desse sistema, de forma
a melhorar o desempenho em mquinas multicore e trazer uma facilidade ao acesso dos
dados da aplicao devido a sua centralizao.
Atravs do contato com colegas da faculdade e de outras empresas da rea de informtica, percebe-se que muitas aplicaes ainda mantm um cdigo sequencial e outras
ainda so programadas de forma sequencial, o que torna esse trabalho interessante para
programadores que tenham interesse na paralelizao de aplicaes.
11
FUNCIONAMENTO DA APLICAO
3.1
Checkout
Trata-se de um aplicativo que inicia uma transao TEF atravs do portador do carto
que interage com essa aplicao. Podemos ter vrios tipos de checkouts, conforme o tipo
de negcio do estabelecimento: Client PDV, Client Mvel, Client Telemarketing e Client
ATM. Nesse trabalho, o estudo foi concentrado no aplicativo Client Mvel, que tem como
funes:
obter a operao desejada, identificando se uma operao com carto de crdito,
dbito, etc, bem como o tipo de transao (compra, consulta, pagamento de contas,
entre outras);
realizar a leitura do carto magntico ou chip do portador, quando necessrio;
realizar a leitura da senha do portador, quando necessrio;
imprimir comprovante da operao TEF, quando necessrio;
realizar a comunicao com o Conversor Client.
3.1.1.1
Client Mvel
Essa soluo possibilita realizar uma TEF atravs de um POS (Point of Sale) sem fio e
com comunicao GPRS, o que possibilita total mobilidade na transao, visto que utiliza
o servio de dados das operadoras de telefonia celular. Tambm podemos ter um POS
sem fio com comunicao Wi-Fi.
12
3.1.2
Conversor Client
3.1.3
TEF Dedicado
Aplicativo que formata e roteia as transaes para cada Rede Autorizadora com conexo dedicada. Alm disso, fornece todo o controle para consultas, tratamento de pendncias e conciliao financeira, possuindo como funes:
receber as parametrizaes necessrias;
3.1.4
Rede Autorizadora
Aplicativo final que aprova ou nega as transaes de cada estabelecimento. ele que
aprova o crdito do portador, emite consultas e realiza todas as transaes financeiras.
3.1.5
Topologia da Aplicao
13
Motivos da Paralelizao
A figura 3.2 mostra todo fluxo transacional, ou seja, o fluxo das transaes de solicitao, resposta e confirmao. A transao de solicitao iniciada com a coleta do carto
e o envio de uma transao de consulta. O aplicativo ConversorPOS recebe essa consulta
e, atravs de consultas a tabelas locais que possuem parmetros de configurao de cada
BIN (seis primeiros digitos do carto), envia uma resposta ao POS. Essa resposta possui
fluxos de captura de alguns dados que devem ser coletados pelo operador do POS. Aps a
coleta dessas informaes, o POS envia uma nova transao que ser encaminhada rede
autorizadora. Aps verificar a validade do carto e outras informaes, a rede autorizadora envia a resposta para o sistema TEF que redireciona a mensagem para o POS. Aps
o recebimento da transao, o POS imprime um comprovante para o cliente final e envia
uma transao de confirmao rede autorizadora.
14
15
FUNDAMENTAO TERICA
4.1
O crescimento do uso de computadores com vrios processadores incentivou o desenvolvimento de programas com processamento paralelo, com capacidade de processamento muito maior.
A programao tradicional, ou em srie, trata as tarefas de forma sequencial, ou seja,
resolvendo tarefa aps tarefa. J na computao em paralelo so realizadas vrias tarefas
em simultneo, uma por processador, aproveitando os vrios processadores disponveis
nas arquiteturas atuais.
Sendo assim, a paralelizao tornou-se um assunto comum entre os estudantes de
informtica que buscam nela solues para problemas de desempenho enfrentados com
programas sequenciais. O uso de threads a opo mais direta para o aproveitamento de
computadores com mltiplas CPUs e memria compartilhada, pois seu modelo coincide
exatamente com o modelo da arquitetura de hardware destas mquinas, com memria
compartilhada (MORALES, 2009).
Muitos trabalhos nessa rea so realizados e podemos destacar alguns que paralelizam
algoritmos (BRINKHUS, 2009) e outros que analisam o desempenho da programao
paralela (PILLA, 2009).
4.2
Threads
Gerenciamento de Threads
necessrio conhecermos algumas operaes bsicas para o gerenciamento das threads: criao, trmino, juno e suspenso.
Criao: os processos normalmente iniciam com apenas uma thread e essa thread
tem a capacidade de criar novas threads. No possvel especificar o espao de
endereo da nova thread, pois ela executa no endereo da thread criadora. thread
criadora retornada um identificador da thread em criao. Aps sua criao uma
16
Sincronizao
Frequentemente threads, assim como processos, precisam trocar informaes entre si.
Pode-se destacar dois tpicos em relao a isso: como as threads no invadem umas as
outras quando envolvidas em atividades crticas e tambm a relao de dependncia entre
as threads.
4.2.2.1
Condies de Disputa
Em alguns sistemas operacionais, processos que trabalham juntos podem compartilhar algum armazenamento comum, a partir do qual cada um capaz de ler e escrever. O
armazenamento compartilhado pode estar na memria principal (possivelmente em uma
estrutura de dados do ncleo) ou em um arquivo compartilhado; o local da memria compartilhada no altera a natureza da comunicao ou dos problemas que surgem. Situaes
como a em que dois ou mais processos esto lendo ou escrevendo algum dado compartilhado e cujo resultado final depende das informaes de quem e quando executa
precisamente so chamadas de condies de disputa (race conditions). A depurao de
programas que contenham condies de disputa no nada divertida. Os resultados da
maioria dos testes no apresentam problemas, mas uma hora, em um momento raro, algo
estranho e inexplicvel acontece. (TANENBAUM, 2003)
4.2.2.2
Regies Crticas
Para evitar condies de disputa aqui e em muitas outras situaes que envolvam memria compartilhada e arquivos compartilhados deve-se encontrar algum modo de impedir que mais de um processo leia e escreva ao mesmo tempo na memria compartilhada.
Em outras palavras, precisamos de excluso mtua (mutual exclusion), isto , assegurar
que outros processos sejam impedidos de usar uma varivel ou um arquivo compartilhado
que j estiver em uso por um processo.
O problema de evitar condies de disputa pode tambm ser formulado de um modo
abstrato. Durante uma parte do tempo, um processo est ocupado fazendo computaes
internas e outras coisas que no acarretam condies de disputa. Contudo, algumas vezes,
um processo precisa ter acesso memria ou a arquivos compartilhados ou tem de fazer
outras coisas crticas que podem ocasionar disputas. Aquela parte do programa em que
h acesso memria compartilhada chamada de regio crtica (critical region) ou seo
crtica (critical section). Se pudssemos gerenciar o processamento de modo que nunca
dois processos estivessem em suas regies crticas ao mesmo tempo, as disputas seriam
evitadas (TANENBAUM, 2003).
17
4.2.2.3
Semforos
Mutexes
4.3
Geralmente, quando h um transbordo da pilha de um processo, o ncleo apenas garante que o processo ganhar mais espao na pilha. Quando temos mltiplas threads,
um processo tambm deve ter mltiplas pilhas. Se o ncleo no souber dessas mltiplas
pilhas ele no poder garantir mais pilhas.
Outro problema que muitas bibliotecas no so reentrantes, ou seja, no esto preparadas para mais de uma chamada aos seus procedimentos ao mesmo tempo.
Normalmente, o cdigo de uma thread executa vrios procedimentos que podem possuir muitas variveis locais, parmetros de procedimentos e variveis globais. As duas
primeiras no geram problemas, mas as variveis globais sim. O problema geralmente
acontece quando mais de uma thread utiliza essa varivel ao mesmo tempo. Como exemplo podemos citar uma varivel global X que modificada por uma thread A e que deveria
ser lida no final de um procedimento dessa thread, mas, antes dessa leitura, uma thread B
ganha o controle da CPU e modifica o valor de X, causando assim um problema quando
a thread A retomar o controle e for ler o valor da varivel X.
18
4.4
POSIX Threads
Sincronizao
19
Esse captulo descreve as dificuldades de portar um cdigo monothread para multithread e detalha as modificaes realizadas no cdigo fonte da aplicao.
5.1
O aplicativo foi desenvolvido na IDE Borland C++ Builder 6.0 e baseia-se em eventos, ou seja, para cada mensagem que o aplicativo recebe de um Checkout POS ou de
uma rede autorizadora, um evento gerado e adicionado em uma lista de eventos. Sequencialmente, os eventos so lidos dessa lista e processados, conforme o cdigo abaixo:
void __fastcall CConversorPOS::tmTimerTimer(TObject *Sender)
{
CEvento
*oEvento;
bool bFim = false;
AnsiString sMensagemErro;
AnsiString sMensagem;
tmTimer->Enabled = false;
try
{
while (!bFim)
{
if (Application != NULL)
Application->ProcessMessages();
else if (Service != NULL)
Service->ServiceThread->ProcessRequests(false);
oEvento = NULL;
oEvento = BuscaEvento();
if (oEvento == NULL)
break;
// processa o evento. Se for evento de finalizao ou erro,
//sai do loop
if (ProcessaEvento(oEvento) != 0)
bFim = true;
delete oEvento;
}
}
20
5.2
Analisando a aplicao, verifica-se a possibilidade da criao de threads para o processamento da fila de eventos, que hoje processada sequencialmente. Por exemplo, se
o aplicativo receber 4 transaes ao mesmo tempo, em vez de process-las uma a uma,
pode-se criar uma rotina como a abaixo para consumir ou processar os eventos presentes na lista.
void CConversorPOS::CriaObjeto(void *pHandle)
{
...
pthread_create(&m_threadId[i], NULL, NovaThread, this);
...
21
}
void *CConversorPOS::NovaThread(void *arg)
{
CEvento
*oEvento;
bool bFinalizaThread = false;
while(bFinalizaThread == false)
{
oEvento = ((CConversorPOS *)arg)->BuscaEvento();
if( oEvento != NULL )
{
if (((CConversorPOS *)arg)->ProcessaEvento(oEvento) != 0)
bFinalizaThread = true;
delete oEvento;
oEvento = NULL;
}
}
pthread_exit((void *)0);
}
Para realizar essa alterao necessrio tratar alguns dos problemas citados no captulo de converso de cdigo monothread para multithread. Analisando a figura 5.1,
verifica-se a utilizao de algumas bibliotecas que, aps testes iniciais, com as modificaes do cdigo acima, fizeram com que o programa travasse. Isso ocorreu por essas
bibliotecas no serem reentrantes, como explicado no captulo 4.
Outro problema que o prprio objeto criado da classe CConversorPOS passado
como parmetro do mtodo NovaThread e isso implica na modificao das variveis compartilhadas por procedimentos utilizados dentro da thread.
5.3
5.3.1
Atividades
Criao da DLL pthread para Windows
22
5.3.2
Aps a gerao da DLL pthreadBC2 necessrio a incluso dessa biblioteca no projeto do Conversor POS e a cpia dos arquivos headers disponibilizados pela (PTHREADSWIN32, 2012) para o diretrio de instalao do C++ Builder.
As figuras 5.2, 5.3, 5.4, 5.5 e 5.6, respectivamente nas pginas 22, 22, 23, 23 e 23,
ilustram esses procedimentos.
23
24
5.3.3
Pthreads x VCL
Aps a paralelizao do cdigo e alguns testes, verificou-se o travamento da aplicao. A figura 5.7 mostra parte do guia do usurio do C++ Builder. Ele diz que alguns
componentes da VCL no so thread-safe, ou seja, no garantem que vrias threads executaro simultaneamente de maneira correta. Ele apresenta uma soluo que seria utilizar
o mtodo Synchronize para garantir thread-safe, mas esse mtodo no existe na biblioteca
pthreads. Foi necessrio ento modificar todas as dlls que utilizavam algum compononente da biblioteca VCL.
5.3.4
A dll conexaotcp.dll utilizava o componente TForm da VCL, conforme pode ser visto
na figura 5.8. Pela anlise realizada, o uso do TForm era apenas para a criao do componente TTimer, mas pode-se cri-lo dinamicamente atravs da chamada new.
25
26
//void
CriaForm(void* Handle);
//void
DestroiForm();
void
setTempoConexao(int iTempo);
void
setTempoDesConexao(int iTempo);
AnsiString getStringConexao();
void
getTabelasParaAuditoria(TStringList *stlTabelas);
};
No mtodo construtor da classe foi criado dinamicamente o objeto TTimer.
CConexaoTCP::CConexaoTCP() : CConexao()
{
setInterface((VInterface*) NULL);
CFilaMensagem *oFilaMensagem;
oFilaMensagem=new CFilaMensagem;
setFilaMensagem(oFilaMensagem);
HandleOriginal=NULL;
oBancoDadosConexaoTCP = NULL;
setEndereco("");
setPorta(0);
TimerConexoes = new TTimer(NULL);
TimerConexoes->OnTimer = TimerConexoesTimer;
TimerConexoes->Enabled = false;
TimerConexoes->Interval = 3000;
TimerDesconexoes = new TTimer(NULL);
TimerDesconexoes->OnTimer = TimerDesconexoesTimer;
TimerDesconexoes->Enabled = false;
TimerDesconexoes->Interval = 3000;
}
5.3.5
27
int
iDiasManutencaoArquivos;
bool
bNaoCriptografa;
bool
bCriptografiaForte;
AnsiString sBaseDebug;
AnsiString sArquivoDebug;
AnsiString sArquivoErro;
AnsiString sArquivoSQL;
FILE
*fd_debug;
FILE
*fd_debug_erro;
FILE
*fd_debug_sql;
CEncriptaAes *oEncriptaAes;
pthread_mutex_t mutex;
public:
CPrintDeb(AnsiString sBaseDebug);
~CPrintDeb();
int
Inicializa(int iNivel, AnsiString sDiretorio, int
iDiasManutencaoArquivos, bool bNaoCriptografa);
void
Finaliza();
void
Grava(int iNivelChamada, const char *fmt, ... );
AnsiString getDiretorio();
};
Parte do cdigo fonte em que se inicializa a varivel mutex no construtor da classe
CPrintDeb verifica-se abaixo.
CPrintDeb::CPrintDeb(AnsiString sBaseDebug)
{
...
this->sBaseDebug = sBaseDebug;
if (Trim(this->sBaseDebug) == "")
this->sBaseDebug = "POS";
fd_debug = NULL;
fd_debug_erro = NULL;
fd_debug_sql = NULL;
//inicializando a varivel mutex
pthread_mutex_init(&mutex, NULL);
...
}
A seguir, encontra-se parte do cdigo fonte em que se protege a regio crtica atravs
das chamadas pthread_mutex_lock e pthread_mutex_unlock, para que apenas uma thread
acesse os dados.
void CPrintDeb::Grava(int iNivelChamada, const char *fmt, ...)
{
char pcDataHora[200];
28
29
}
//destrava mutex
pthread_mutex_unlock(&mutex);
}
5.3.6
30
O aplicativo criava apenas uma instncia das DLLs das Redes Autorizadoras, o que
causava travamentos dentro dessas DLLs, pois as threads acessavam o mesmo objeto ao
mesmo tempo. Esse problema foi resolvido criando uma instncia para cada thread que
acessa a DLL. No cdigo fonte antigo, a DLL era instanciada na criao dos objetos da
classe CConversorPOS. Apenas um objeto era criado, como mostrado abaixo em parte do
cdigo.
void CConversorPOS::CriaObjetos(void *pHandle)
{
oControladorTransacoes = new CControladorTransacoesPOS();
oFilaEventos = new CFilaEventos();
oConfiguracaoConversorPOS = new CConfiguracaoConversorPOS();
oPrintDeb = new CPrintDeb("conversorpos");
oTemporizador = new CTemporizador(oFilaEventos, pHandle);
oIOPDV = (VIoPDV *) NewObjeto("IoPdvTcp.dll");
oInterfacePDV = (VInterface *) NewObjeto("InterfaceTCPIP.dll");
oConexaoPDV = (VConexao *) NewObjeto("ConexaoTCP.dll");
oConexaoPDV->setCodigoConexao(CONEXAOPDVTCP);
31
32
CEncriptaAes();
~CEncriptaAes();
int InicializaN();
int FinalizaN();
int CriptografaBufferN(int iTamBuffer, char *pBuffer, ...);
int DesCriptografaBufferN(int iTamBufferCripografado, ...);
static int Inicializa();
static int Finaliza();
static int CriptografaDadosNumericos(char *Chave, ...);
static int DesCriptografaDadosNumericos(char *Chave, ...);
static int CriptografaDadosAlfaNumericos(char *Chave,...);
static int DesCriptografaDadosAlfaNumericos( ...);
static int CriptografaCartao(int NroBit, char *Chave,...);
static int DesCriptografaDadosBinarios(char *Chave, ...);
static int CriptografaDadosBinarios(char *Chave, ...);
static int CriptografaBuffer(int iTamBuffer, ...);
static int DesCriptografaBuffer(int iTam, ...);
};
Um exemplo de como era a chamada dos mtodos dessa classe pode ser visto abaixo em
parte do cdigo fonte.
int CClientPOS::GravaComprovante(AnsiString sNomeArquivo, AnsiString
sComprovante, bool bGravarUltimoComprovante, int iTipoTransacao)
{
...
sChave="7466214";
// montagem da chave de criptografia em duas partes
sChave=sChave+AnsiString("983672106");
ptrDescript = new char[(sComprovante.Length())+512];
CEncriptaAes::CriptografaBuffer(sComprovante.Length(),
sComprovante.c_str(), sChave.c_str(),
&iTamBuffer,ptrDescript);
sComprovanteOriginal = AnsiString(ptrDescript,iTamBuffer);
delete [] ptrDescript;
...
}
Como mostrado acima, a classe no foi instanciada e foi utilizado um dos mtodos declarados como esttico.
A modificao foi retirar os mtodos estticos declarados na classe e tambm instanciar um objeto da classe para o uso dos mtodos, como podemos ver abaixo em parte do
cdigo fonte modificado.
int CClientPOS::GravaComprovante(AnsiString sNomeArquivo, AnsiString
sComprovante, bool bGravarUltimoComprovante, int iTipoTransacao)
{
33
.
.
.
CEncriptaAes *oEncriptaAes;
oEncriptaAes =new CEncriptaAes();
oEncriptaAes->Inicializa();
sChave="7466214";
// montagem da chave de criptografia em duas partes
sChave=sChave+AnsiString("983672106");
ptrDescript = new char[(sComprovante.Length())+512];
oEncriptaAes->oCriptografaBuffer(sComprovante.Length(),
sComprovante.c_str(), sChave.c_str(),
&iTamBuffer, ptrDescript);
sComprovanteOriginal = AnsiString(ptrDescript,iTamBuffer);
oEncriptaAes->Finaliza();
delete oEncriptaAes;
delete [] ptrDescript;
...
}
5.3.9
Foi desenvolvido um aplicativo para testes de estresse que pode simular diversos POS
enviando transaes simultneas. Ele servir para criar uma base de dados para uma
melhor visualizao dos resultados obtidos com a paralelizao.
34
5.4
Anlise da Implementao
Paralelizar essa aplicao com a biblioteca pthreads foi uma tarefa complicada, pois
no h mtodos que simplificam essa execuo. Primeiramente, foi necessrio analisar
todo o cdigo do programa para implementar as novas threads. Em seguida, foram analisadas as DLLs que eram instanciadas apenas uma vez e acessadas ao mesmo tempo
pelas threads. Isso gerou os problemas das DLLs no reentrantes, conforme citado na
seo 4.3. Foi adotado como soluo a criao de vrias instncias das DLLs, uma para
cada thread. Tambm foram analisados os pontos em que existiam dados compartilhados
para essas threads e, utilizando mecanismos de sicronizao como semforos, evitou-se o
acesso simultneo dessas regies crticas.
Mesmo com essas anlises e modificaes, aps executar o aplicativo ocorreram deadlocks e, para encontr-los, teve-se que depurar a aplicao. Um dos erros verificados
com a depurao foi o acesso simultneo dos mtodos estticos pelas threads, como mostrado na subseo 5.3.8. Tambm foram encontrados, aps a depurao, os problemas
com o uso dos componentes da VCL, conforme citado na subseo 5.3.3.
Aps muitos testes, pde-se sanar a maioria dos erros que ocorriam, mas esse mtodo
de tentativa e erro no o mais adequado, j que no eficiente quanto ao tempo e tambm
no garante que a aplicao esteja corretamente paralelizada, pois seria necessrio muito
tempo para realizar todos os testes.
35
6.1
RESULTADOS OBTIDOS
Nos testes foram utilizados dois computadores pessoais da fabricante Dell, modelo
Optiplex 990, sistema operacional Windows 7 Professional, processador Intel(R) Core(TM)
i5-2400, CPU de 3.10 GHz e memria RAM de 4 GB. A partir da necessidade de os aplicativos comunicarem-se atravs de conexes TCP, os computadores foram ligados em
uma rede local de 100 Gigabits. Para uma melhor compreenso, iremos referenciar os
dois programas que foram utilizados nos testes como monothread e multithread que,
respectivamente, possuem programao sequencial e paralela. Em um dos computadores foi instalado o aplicativo benchmark que simula diversos POS e no outro computador foram instalados os programas monothread e multithread. Configurando o aplicativo
benchmark para 1, 10, 30, 60, 150, 300 e 600 POS, foi realizada uma bateria de testes
individuais de 5 minutos com os aplicativos monothread e multithread. Utilizou-se o aplicativo Monitor de Recursos do prprio Windows para analisar o uso da CPU e dos outros
recursos das mquinas. Mediu-se, tambm, a quantidade de transaes por segundo em
tomadas de tempo.
6.2
Testes e Resultados
Essa seo apresenta e compara os grficos e figuras obtidos a partir das tomadas de
tempo realizadas com os programas monothread e multithread.
36
37
38
Os testes realizados simulando 10 POS tiveram resultados parecidos em termos de clculo de throughput entre os aplicativos monothread e multithread. Analisando os grficos
de uso da CPU percebe-se que nenhuma das aplicaes utilizou toda a CPU disponvel.
Assim, pode-se concluir que quando no temos 100% do uso da CPU pelo aplicativo
monothread o ganho de performance do aplicativo multithread pequeno em relao ao
monothread, como pode ser visto nas figuras 6.1 e 6.2.
39
40
41
Os testes realizados com 60 POS tiveram resultados bem distintos. O aplicativo monothread teve um desempenho de 66,97 TPS e o multithread de 159,49 TPS. Nesse teste
consegue-se ter uma visualizao melhor do desempenho da programao paralela, que
utiliza todas as CPUs disponveis para a obteno de uma melhor performance, conforme
pode ser visto na figura 6.8. Visualiza-se, tambm, que a CPU utilizada pelo programa
monothread est em 100% do uso e pode-se verificar nos prximos testes que o desempenho dessa aplicao no ter uma melhora.
42
43
44
Nos testes realizados com carga de 150 POS, o aplicativo multithread obteve uma melhora no seu desempenho, aumentando o nmero de transaes por segundo para 277,44.
J no aplicativo monothread o desempenho ficou estagnado. Verifica-se essa anlise nas
figuras 6.9 e 6.10. Com relao ao uso das CPUs, pode-se verificar nas figuras 6.11 e 6.12
que o aplicativo monothread continua com uso de 100% da CPU e o aplicativo multithread distribui o trabalho para as CPUs disponveis, utilizando apenas 25%. Como houve
uma estagnao para o aplicativo monothread, no necessrio apresentar outros testes
para ele, pois o desempenho e o uso da CPU continuaro os mesmos. Para o aplicativo
multithread, a carga de transaes simultneas foi aumentada a fim de visualizar a capacidade mxima da programao paralela, j que ainda havia um bom percentual livre do
uso das CPUs.
45
46
47
Os testes com carga de 300 e 600 POS com o aplicativo multithread geraram alguns
resultados inesperados. O desempenho do benchmark com 300 POS foi de 321,96 TPS, e
com 600 POS foi de 287,05 TPS. Analisando o grfico de uso das CPUs verifica-se que o
teste com 300 POS teve um maior uso da CPU do que o teste com 600 POS. Sendo assim,
foi necessrio descobrir o motivo para que isso tenha ocorrido. Analisando os grficos de
memria, HD e rede verificou-se um desempenho normal nos dois testes, ou seja, sem
chegar a 100% do uso desses recursos. O nico grfico que estava anormal era o de
conexes TCP, em que aparecia de maneira intermitente 100% e 0% do uso, como pode
ser visto na figura 6.17. Aps essa anlise, verificamos se o problema estaria na aplicao
benchmark que gera as transaes, considerando que essa aplicao fosse duplicada em
outra mquina. Aps essas modificaes, verificou-se uma melhora no desempenho da
aplicao multithread que recebia transaes de 600 POS, enviados por duas mquinas. O
desempenho dos benchmarks foi de 202 TPS e 218 TPS, totalizando um desempenho de
420 TPS, conforme as figuras 6.18 e 6.19. Um maior uso das CPUs, conforme esperado,
tambm ocorreu, o que pode ser verificado na figura 6.20.
48
Figura 6.17: Conexes TCP - Aplicativo Multithread recebendo transaes de 600 POS
49
50
6.3
Os benchmarks apresentados avaliaram todo o ambiente de testes das aplicaes programadas de maneira sequencial e paralela. O grfico da figura 6.23 e a tabela 6.22 comparam os ciclos de testes realizados variando de 1 a 800 o nmero de POS, que enviam as
transaes de forma simultnea.
51
52
CONSIDERAES FINAIS
53
REFERNCIAS
BRINKHUS, R. Algoritmo Gentico Paralelo: avaliao de diferentes abordagens na soluo de um problema inverso em vibraes. 2009. Salo de Iniciao Cientfica - Instituto
de Informtica, Universidade Federal do Rio Grande do Sul, porto Alegre. 2009.
CARISSIMI, A. S. ; TOSCANI, S. S. ; OLIVEIRA, R. S. Sistemas Operacionais. 2a. ed.
Porto Alegre : Sagra Luzzato, 2004.
Cygwin. Cygwin Project. Disponvel em: <http://cygwin.com>. Acessado em junho de
2012.
GHEZZI, Carlo; Jazayeri, Mebdi. Conceitos de linguagens de programao. - Rio de
Janeiro: Campus, 1991.
LIMA, J. Controle de Granularidade com threads em Programas MPI Dinmicos. 2009.
65 f. Dissertao(Mestrado em Cincia da Computao) - Instituto de Informtica, Universidade Federal do Rio Grande do Sul, Porto Alegre. 2009.
MORALES, D. Compilao de Cdigo C/MPI para C/PThreads. 2009. 61 f. Monografia(Graduao em Cincia da Computao) - Instituto de Informtica, Universidade Federal do Rio Grande do Sul, Porto Alegre. 2009.
PILLA, L. Anlise de perfis paralelos em processadores grficos. 2009. Salo de Iniciao Cientfica - Instituto de Informtica, Universidade Federal do Rio Grande do Sul,
Porto Alegre. 2009.
Pthreads Win32. Open Source POSIX Threads for Win32. Disponvel em:
<http://sourceware.org/pthreads-win32/>. Acessado em junho de 2012.
SEBESTA, Robert W. Conceitos de Linguagens de Programao. - 4. ed. - Porto Alegre:
Bookman, 2000.
TANENBAUM, A. S. Sistemas Operacionais Modernos. 2a. ed. Pearson, 2003.