SlideShare uma empresa Scribd logo
1 de 21
Baixar para ler offline
Servidor com processamento paralelo utilizando CUDA
aplicado em uma urna eletrˆonica
Douglas A. Cunha1
, Rafael R. P. Araujo2
1
Centro Universit´ario IESB
CEP: 70.200-730 – Bras´ılia – DF – Brazil
2
Ciˆencia da Computac¸˜ao – Centro Universit´ario IESB
Bras´ılia, Brazil
{douglasxxdouglas,bsb.rafaelaraujo}@gmail.com
Abstract. The present research aims to identify and develop through the
integration of the companies analyzed, a set of valid data, count and manipulate
the data sent by each state of the federation. The study, looked for more
profitable algorithms, since, the value of stresses was of 1 billion of registries.
For the development of the work several technologies were used, in particular,
a programming language for the decision making on the ability to optimize the
time for the validation as the counting of votes through the parallelism and use
of the video card as processing source. The reflection of the research, turned
into the algorithms developed and tested in the most diverse languages, the
most perfomatic CUDA was used. In addition, it was possible to obtain a final
count of the votes of the election.
Keywords: CUDA. Server. Validation.
Resumo. A presente pesquisa visa identificar e desenvolver atrav´es da
integrac¸˜ao das mat´erias anteriormente estudadas, um servidor capaz de
validar, contar e manipular os dados enviados por cada estado da federac¸˜ao.
O estudo buscou identificar os algoritmos mais perform´aticos, uma vez que,
o valor de estresse estipulado foi de um bilh˜ao de registros. Para o desen-
volvimento do trabalho foram utilizadas diversas tecnologias, em especial, a
linguagem de programac¸˜ao CUDA para que fosse poss´ıvel aperfeic¸oar/otimizar
o tempo tanto de validac¸˜ao como de contagem de votos atrav´es do paralelismo
e uso da placa de v´ıdeo como fonte processadora. O reflexo da pesquisa
mostrou que dentre os diversos algoritmos desenvolvidos e testados nas mais
diversas linguagens, o mais perform´atico foi utilizando CUDA. Al´em disso, foi
poss´ıvel obter a contagem final dos votos da eleic¸˜ao.
Palavras-chave: CUDA. Servidor. Validac¸˜ao.
1. Siglas
• ANSI - American National Standard Institute
• API - Interface de Programac¸˜ao de Aplicac¸˜ao
• BSD - Berkeley Software Distribution
• CPU - Unidade Central de Processamento
• GPGPU - A Unidade de Processamento Gr´afico de Prop´osito Geral
• GPU - Unidade de Processamento Gr´afico
• ISA’s - Instruction Set Architecture
• RAM - Mem´oria de Acesso Aleat´orio
• WSGI - Interface de Porta de Entrada do Servidor Web
• HTML - HyperText Markup Language
• CSS - Cascading Style Sheets
2. Introduc¸˜ao
A cada quatro anos ´e realizado por todo o pa´ıs uma eleic¸˜ao com o intuito de escolher
candidatos que ir˜ao governar durante um determinado per´ıodo de tempo. Dessa forma,
ap´os muitos anos a forma de apurac¸˜ao dos votos serem utilizadas atrav´es de papeis e
contados por pessoas, criou-se o atual sistema e mecanismo de voto, o coletor eletrˆonico
de voto.
O coletor eletrˆonico de voto, tamb´em conhecido como urna eletrˆonica, ´e uma
m´aquina/mecanismo de votac¸˜ao que ir´a registrar os votos dos eleitores em mem´orias in-
ternas que posteriormente ser˜ao enviadas para um terminal.
Nos centros urbanos, em cada local de votac¸˜ao tem um terminal de acesso ao
sistema interno da Justic¸a Eleitoral. Atrav´es dessa rede que as informac¸˜oes referentes a
cada urna ser˜ao enviadas para o Tribunal Regional Eleitoral de cada estado da federac¸˜ao.
Essas informac¸˜oes s˜ao transmitidas atrav´es de uma estrutura de comunicac¸˜ao pr´opria que
´e fornecida pelas operadoras de telefonia. Dessa forma, ap´os o fim do hor´ario eleitoral,
os locais ir˜ao se conectar atrav´es de uma intranet (rede privada), pela qual as informac¸˜oes
ser˜ao transmitidas. [TSE ]
Com as informac¸˜oes no servidor referente a cada urna eletrˆonica, o mesmo comec¸a
a contagem e processamento dos dados fornecendo ao final, o candidato eleito. No en-
tanto, apesar de possuir especialistas e pessoas extremamente capacitadas que cuidam e
desenvolvem algoritmos e processos inteligentes e r´apidos, algumas abordagens podem
passar despercebidas ou at´e mesmo ignoradas. Dessa forma, o presente artigo ir´a abordar
diversos algoritmos testados at´e que cheg´assemos ao resultado final mais perform´atico
com relac¸˜ao `a validac¸˜ao, contagem e processamento desses dados.
2.1. Motivac¸˜ao
O n´umero de trabalhos relacionados a algoritmos de estrutura de dados aplicados `a uma
urna ´e bastante reduzido, dessa forma, com a motivac¸˜ao de contribuir para que a comu-
nidade tenha acesso a diferentes modelos e sistemas de urna eleitoral, foi desenvolvido
o presente artigo. Al´em disso, o assunto abordado foi motivado e incentivado por nosso
orientador. Por fim, o poder computacional proposto no presente artigo nos motivou ainda
mais em prosseguir com a ideia de usar processamento paralelo e CUDA.
2.2. Hip´otese
Antes de se iniciar o desenvolvimento do servidor, conversamos sobre qual abordagem
ir´ıamos seguir, bem como, os poss´ıveis resultados esperados. No entanto, no decorrer do
desenvolvimento do projeto, fomos encontrando pontos e indicativos de que as estrat´egias
adotadas n˜ao seriam as melhores, esses indicativos foram poss´ıveis de serem vistos, uma
vez que, a quantidade de linhas que teriam de ser processadas, bem como, a quantidade de
arquivos recebidos simultaneamente precisaria de um poder computacional muito grande
e atrav´es do uso de recursos mais simples isso n˜ao seria poss´ıvel. Para resolvermos o
problema utilizamos a integrac¸˜ao entre duas linguagens (C e Python) realizando o proces-
samento atrav´es da placa de v´ıdeo e o processamento paralelo.
2.3. Objetivos e Desafios da Pesquisa
Durante a pesquisa e desenvolvimento do presente artigo, alguns desafios tiveram de ser
enfrentados, dentre eles a demora em gerar massas de testes, a limitac¸˜ao da mem´oria
RAM dos nossos computadores pessoais dificultando na leitura de grande quantidade
de linhas, a necessidade de integrac¸˜ao de duas linguagens distintas (Python e C) e do
estudo/implemenac¸˜ao do CUDA. Al´em disso, como a comunidade do CUDA ainda ´e
pequena, ent˜ao, as soluc¸˜oes para alguns problemas s˜ao bastante complexas e dif´ıceis de
serem encontradas, dessa forma, por vezes ficamos impossibilitados de prosseguir no
desenvolvimento tendo de procurar outras sa´ıdas e soluc¸˜oes. A an´alise da complexidade
dos algoritmos tamb´em se tornou um desafio ao longo da pesquisa.
• Objetivo Geral
– Produc¸˜ao de um servidor respons´avel pela manipulac¸˜ao, validac¸˜ao e con-
tagem dos votos enviados por cada estado da federac¸˜ao.
• Objetivos espec´ıficos
– Analisar os tempos de execuc¸˜ao de cada algoritmo desenvolvido;
– Comparar as diferentes tecnologias com a finalidade de encontrar a que
oferece melhor desempenho de acordo com o objetivo geral proposto.
2.4. Contribuic¸˜oes
O presente artigo ir´a contribuir para testar a integralidade dos arquivos. Al´em disso,
o nosso trabalho contribuir´a para a contabilizac¸˜ao total dos votos da eleic¸˜ao simulada,
tamb´em ser´a poss´ıvel extrair atrav´es desse trabalho, diferentes algoritmos que poder˜ao ser
utilizados para o estudo da mat´eria estrutura de dados. O presente artigo poder´a contribuir
no desenvolvimento de outras aplicac¸˜oes que fazem uso da API CUDA, uma vez que, a
comunidade do CUDA ´e bastante reduzida, a publicac¸˜ao desse artigo poderia ajudar as
pessoas a criarem suas pr´oprias aplicac¸˜oes/projetos.
2.5. Organizac¸˜ao da Dissertac¸˜ao
O trabalho est´a dividido em cinco cap´ıtulos, os quais se descrevem resumidamente a
seguir:
• Sec¸˜ao 2 – Introduc¸˜ao: aborda a motivac¸˜ao, objetivos e desafios da pesquisa,
hip´otese, contribuic¸˜oes e organizac¸˜ao da dissertac¸˜ao.
• Sec¸˜ao 3 – Fundamentac¸˜ao Te´orica: aborda a fundamentac¸˜ao te´orica das tecnolo-
gias usadas e os trabalhos correlatos.
• Sec¸˜ao 4 – Proposta e Desenvolvimento: apresenta a proposta da pesquisa, bem
como, os passos do desenvolvimento do servidor.
• Sec¸˜ao 5 – Experimentos e An´alise dos Resultados: apresenta a metodologia usada,
experimentos e a avaliac¸˜ao dos resultados.
• Sec¸˜ao 6 – Conclus˜ao e Trabalhos Futuros: s˜ao feitas as considerac¸˜oes finais, al´em
das propostas de trabalhos futuros.
• Sec¸˜ao 7 – Referˆencias: referˆencias usadas ao longo do desenvolvimento do pre-
sente artigo, bem como, no desenvolvimento da aplicac¸˜ao.
• Sec¸˜ao 8 – Imagens: imagens usadas no presente artigo.
3. Fundamentac¸˜ao Te´orica
3.1. Tecnologias
Para que fosse poss´ıvel o desenvolvimento do servidor, foram utilizadas as seguintes tec-
nologias:
• Editor de C´odigo Fonte:
– Visual Studio Code
• Linguagens de programac¸˜ao:
– C
– Python
• API:
– CUDA
• Framework:
– Flask
• Recursos Computacionais:
– Processamento Paralelo
– Processamento Paralelo com API CUDA.
3.2. Editor de C´odigo Fonte Visual Studio Code
O editor de c´odigo-fonte foi desenvolvido em 2015 pela Microsoft para Windows, Linux
e macOS, o mesmo inclu´ı suporte para depurac¸˜ao, controle do GIT incorporado, realce
de sintaxe, complementac¸˜ao de c´odigo, snippets e refatorac¸˜ao de c´odigo. O Visual Studio
Code ´e baseado no Electron, um framework usado para desenvolver aplicativos Node.js
para o desktop rodando no motor de layout blink. A decis˜ao da escolha pela IDE levou
em conta a compatibilidade com as linguagens que foram usadas no projeto, bem como,
a inteligˆencia da mesma para refatorac¸˜ao de c´odigos quando necess´ario, al´em disso, do
baixo consumo de recursos computacionais durante o uso. [Microsoft ]
3.3. Linguagem de Programac¸˜ao C
A linguagem de programac¸˜ao C foi criada por volta dos anos 70 e implementada em um
computador nomeado de DEC PDP-11 por Dennis Ritchie. O C tem sua origem a partir de
outras duas linguagens: Algol 68 e BCPL. Inicialmente o uso da linguagem era destinado
ao desenvolvimento de sistemas operacionais e compiladores. Essa linguagem foi usada
na construc¸˜ao de uma nova vers˜ao do sistema operacional Unix, que inicialmente, foi
escrito em Assembly. Com o grande sucesso desse desenvolvimento, a linguagem ganhou
mais adeptos e, portanto, nos dias atuais, a maiora todos os grandes sistemas operacionais
s˜ao constru´ıdos em C.
Apesar de todos os esforc¸os e a grande quantidade de usu´arios fazendo uso da
linguagem, ela ainda n˜ao era uma linguagem padronizada. Por volta dos anos 80 o C j´a
contava com uma gama de compiladores, no entanto, apesar do grande n´umero ainda ex-
istiam diversas diferenc¸as ocasionando na incompatibilidade entre eles. Nesse momento,
a padronizac¸˜ao da linguagem foi iniciada em 1983 pela ANSI e finalizada em 1989.
Utilizaremos a linguagem C, pois como a mesma ´e uma linguagem de proposito
geral, ou seja, a adaptabilidade na maioria dos projetos ´e extremamente alta. No entanto,
um segundo e mais importante ponto que analisamos para realizar a escolha foi a sua
velocidade em tempo de execuc¸˜ao. O C diferente de outras linguagens ´e extremamente
r´apido em tempo de execuc¸˜ao devido `a arquitetura em que foi desenvolvida. Isso ocorre,
pois linguagens como Java, Basic, Perl, dentre outras s˜ao linguagens a base de byte-
code interpretados por uma m´aquina virtual, enquanto no C, a interpretac¸˜ao do c´odigo
´e realizada diretamente pelo processador. Al´em disso, atrav´es do C ´e poss´ıvel realizar
enderec¸amentos de mem´oria de maneira bastante parecida como ´e feito em Assembly.
Dessa forma, em aplicac¸˜oes que exigem tarefas de baixo-n´ıvel, ou seja, que ne-
cessitam do acesso direto a mem´oria, como por exemplo, a c´opia de bytes para uma placa
de rede ou de v´ıdeo, s´o ´e poss´ıvel atrav´es do C. Por fim, o C permite a personalizac¸˜ao
de diversos algoritmos pr´e-implementados, como por exemplo, a alocac¸˜ao de mem´oria,
com o objetivo de melhorar o desempenho ou at´e mesmo adaptar de acordo com a sua
necessidade.[Schildt 1996]
3.4. Linguagem de Programac¸˜ao Python
A linguagem de programac¸˜ao Python foi criada por volta dos anos 90 por Guido Van
Rossum. O python possu´ı um modelo de desenvolvimento comunit´ario, aberto e geren-
ciado pela organizac¸˜ao Pyhon Software Foundation(https://www.python.org/).
Atrav´es do link informado anteriormente, tamb´em ´e poss´ıvel encontrar no site o download
da linguagem, bem como, as diferentes implementac¸˜oes, a documentac¸˜ao, dentre outros
recursos.
A linguagem foi projetada de forma a priorizar e enfatizar a importˆancia do
esforc¸o do programador sobre o esforc¸o computacional, ou seja, a linguagem prioriza
a legibilidade do c´odigo sobre a velocidade. Possu´ı uma combinac¸˜ao entre a sintaxe con-
cisa e clara com os recursos poderosos da biblioteca padr˜ao, bem como, os m´odulos e
frameworks desenvolvidos pela comunidade. Al´em disso, ´e uma linguagem de alto n´ıvel,
multi-paradigma, ou seja, suporta paradigma orientado a objetos, imperativo funcional
e procedural. Por fim, ´e uma linguagem bastante utilizada no processamento de textos,
dados cient´ıficos, dentre outras ´areas. [Tulchak and Marchuk ]
Utilizamos a linguagem Python no projeto, pois a mesma oferece um recurso de
integrac¸˜ao com a linguagem C, al´em disso, torna poss´ıvel atrav´es do framework Flask, o
desenvolvimento da aplicac¸˜ao web.
3.5. CUDA
Anteriormente, a API CUDA era conhecida por Compute Unified Device Architecture e ´e
destinada a computac¸˜ao paralela, GPGPU e computac¸˜ao heterogˆenea criada pela empresa
Nvidia, destinada a placas gr´afica com chipset da Nvidia. A plataforma fornece acesso
ao conjunto de instruc¸˜oes virtuais da GPU e tamb´em a elementos da computac¸˜ao paralela
para a execuc¸˜ao de n´ucleos de computac¸˜ao.
A API possu´ı um conjunto de instruc¸˜oes CUDA ISA’s, al´em do mecanismo de
computac¸˜ao paralela na GPU. Ele exp˜oe os tipos de mem´oria da placa de v´ıdeo e torna
obrigat´orio por parte do desenvolvedor que configure os acessos da mem´oria global,
cache, bem como, a disposic¸˜ao e quantidade dos threads. Por fim, tamb´em ´e de respons-
abilidade do desenvolvedor escalonar as atividades entre a GPU e CPU.
A proposta inicial da Nvidia era que a API fosse destinada a propriedades f´ısicas
em jogos, analisar fluxo do tr´afego, visualizac¸˜ao de mol´eculas e identificar placas ocul-
tas em art´erias. Entretanto, muitos desenvolvedores ao redor do mundo observaram no
CUDA uma tentativa e oportunidade de aprimorar suas aplicac¸˜oes. Dessa forma, out-
ras ´areas comec¸aram a fazer uso da API, como por exemplo: inteligˆencia artificial (o
framework da Google TensorFlow, faz uso do CUDA) e redes blockchain. Nos dias de
hoje, a plataforma CUDA, ´e das plataformas, de GPGPU mais robustas que existem, jus-
tificando assim o prec¸o mais alto de suas placas gr´aficas comparadas com as de suas
concorrentes. Por fim, nas vers˜oes antigas do CUDA Toolkit, era poss´ıvel fazer uso da
ferramenta mesmo sem possuir uma placa gr´afica, atrav´es de um emulador, era poss´ıvel
desenvolver. No entanto, a partir da vers˜ao 3.0, a Nvidia removeu essa funcionalidade.
[Nvidia ]
Utilizamos a API CUDA no projeto, pois a mesma oferece um poder computa-
cional que em combinac¸˜ao com a programac¸˜ao paralela, aumentar´a o desempenho da
nossa aplicac¸˜ao.
3.6. Flask
O Flask ´e um framework web desenvolvido e escrito na linguagem de programac¸˜ao
Python, baseado nas bibliotecas WSGI Werkzeug e Jinja2. Al´em disso, o Flask ´e disponi-
bilizado sob os termos da licenc¸a BSD. Na p´agina do mesmo, ´e poss´ıvel encontrar uma
breve descric¸˜ao sobre a ferramenta, onde atrav´es da pr´opria p´agina, ele ´e chamado de
micro framework, pois mantem um n´ucleo bastante simplificado, no entanto, estend´ıvel.
Isso ocorre, pois n˜ao h´a uma camada de abstrac¸˜ao do banco de dados, validac¸˜ao de for-
mul´arios, ou outros componentes semelhantes. Dessa forma, o Flask suporta diversas
extens˜oes que s˜ao capazes de adicionar e prover tais funcionalidades. [Flask ]
A escolha do micro framework foi bastante clara e objetiva, uma vez que, para que
a parte web da nossa aplicac¸˜ao funcionasse como n´os gostar´ıamos, n˜ao era necess´ario um
framework completo com diversos recursos embutidos que acabar´ıamos n˜ao utilizando.
Dessa forma, o Flask nos permitiu adicionar somente as extens˜oes e funcionalidades que
de fato utilizamos em nossa aplicac¸˜ao.
3.7. Processamento Paralelo
O processamento paralelo (parallel processing) ´e uma forma eficiente do processamento
da informac¸˜ao com ˆenfase na explorac¸˜ao de eventos simultˆaneos na execuc¸˜ao de um soft-
ware. A motivac¸˜ao para o processamento paralelo ´e a possibilidade de aumentar a capaci-
dade de processamento de uma ´unica m´aquina. Com a limitac¸˜ao tecnol´ogica da veloci-
dade das m´aquinas sequenciais, a soluc¸˜ao empregada para aumentar o poder de proces-
samento ´e a utilizac¸˜ao de processadores em paralelo. Assim, com o paralelismo torna-se
poss´ıvel ultrapassar as limitac¸˜oes impostas pela utilizac¸˜ao de um ´unico processador, tais
como frequˆencia de operac¸˜ao, dissipac¸˜ao de potˆencia e outras.
A utilizac¸˜ao do paralelismo nos projetos de arquitetura de computadores tem pos-
sibilitado um aumento significativo na velocidade de processamento devido `a execuc¸˜ao
simultˆanea de diversas tarefas. Contudo, os aspectos relacionados ao software paralelo
e `a paralelizac¸˜ao dos programas s˜ao essenciais para o desempenho do sistema paralelo.
[Ferlin 2011]
Al´em disso, um thread tamb´em pode ser entendido como um processo que pode
pertencer a uma aplicac¸˜ao ou a aplicac¸˜oes completamente distintas e independentes.
Sistemas com um ´unico processador podem gerenciar v´arios threads simultaneamente
atrav´es de m´etodos de Time Slice, fornecendo para cada processo uma fatia de tempo
da CPU (n˜ao necessariamente o mesmo tempo para todos os processos). Dito isso, cada
processo pode conter um n´ıvel de prioridade: os threads com alta prioridade podem in-
terromper threads de menor prioridade. No entanto, por melhor que seja o gerenciamento
dos threads por parte da aplicac¸˜ao ou do sistema operacional, o Time Slice sempre pode
trazer certa lentid˜ao/latˆencia, devido o compartilhamento de cache ou a dificuldade de
gerenciamento entre o trˆansito de processos. [Tanenbaum 2015]
A escolha de se usar o recurso computacional do processamento paralelo se deu,
uma vez que, quer´ıamos acelerar os procedimentos de validac¸˜ao de CPF, Regi˜ao e Con-
tagem dos votos.
3.8. Trabalhos Correlatos
O n´umero de pesquisas, trabalhos e artigos voltados para o desenvolvimento ou estudo
do sistema eleitoral ´e quase que inexistente, a maior parte das buscas realizadas retornam
resultados ligados diretamente ao governo, de forma que, os c´odigos s´o est˜ao dispon´ıveis
aos candidatos ao governo e especialistas da ´area. Dessa forma, a escolha pelo trabalho
correlato levou em conta as ferramentas e tecnologias que usamos no desenvolvimento
do presente artigo, n˜ao necessariamente abrangendo algoritmos semelhantes ao usado por
n´os, uma vez que, n˜ao foi poss´ıvel encontrar trabalhos e pesquisas s´olidas na ´area de
servidores ligados ao sistema eleitoral como um todo.
TensorFlow:
O TensorFlow ´e uma biblioteca de c´odigo aberto com o prop´osito voltado para
o aprendizado de m´aquina aplic´avel a uma ampla variedade de tarefas. Dito isso, ´e um
sistema para treinamento e criac¸˜ao de redes neurais capazes de detectar e decifrar padr˜oes
e correlac¸˜oes, `a forma como humanos aprendem e raciocinam. O TensorFlow foi desen-
volvido pela equipe Google Brain para uso interno na empresa e aos poucos est´a substi-
tuindo o seu antecessor DistBelief. A biblioteca foi lanc¸ada em 2015 sob a licenc¸a de
c´odigo aberto Apache 2.0.
O TensorFlow est´a dispon´ıvel nas vers˜oes de 64 bits Windows, MacOs, Linux e
computac¸˜ao m´ovel, incluindo Android e iOS. Dessa forma, apesar da implementac¸˜ao de
referˆencia sugira que a mesma seja executada em dispositivos individuais, a biblioteca
tamb´em pode ser executada em m´ultiplas CPU’s e GPU’s (com extens˜oes opcionais
CUDA para GPGPU). [TensorFlow ]
4. Proposta e Desenvolvimento
4.1. Proposta
Temos como objetivo/proposta o desenvolvimento de uma aplicac¸˜ao, atrav´es do uso da
programac¸˜ao paralela juntamente da API CUDA, que ser´a respons´avel por receber ar-
quivos no formato .txt com um cabec¸alho pr´e-definido e, ap´os o recebimento do arquivo,
iniciar a validac¸˜ao do CPF por eleitor, bem como, o n´umero do candidato escolhido. Por
fim, ser´a feita a contagem total dos votos que indicar´a o candidato que ser´a eleito.
4.2. Desenvolvimento
Para que o desenvolvimento do presente artigo pudesse ser realizado, foi preciso fazer
uso de tecnologias distintas (citadas na sec¸˜ao 2). Dessa forma, o desenvolvimento da
aplicac¸˜ao foi separado por etapas. S˜ao elas:
• Etapa 1 - Prot´otipo em HTML e CSS da tela web.
• Etapa 2 - Implementac¸˜ao da parte web.
• Etapa 3 - Algoritmo de validac¸˜ao do arquivo.
• Etapa 4 - Algoritmo de validac¸˜ao de CPF.
• Etapa 5 - Algoritmo de validac¸˜ao da Regi˜ao.
• Etapa 6 - Algoritmo de contagem dos votos.
• Etapa 7 - Fila de processamento.
Para cada etapa listada acima, ser´a definido o modelo de implementac¸˜ao, carac-
ter´ıstica de cada etapa e sua importˆancia no projeto, complexidade do algoritmo, dentre
outras definic¸˜oes.
4.3. Prot´otipo em HTML e CSS da tela web
No modelo eleitoral existente no Brasil hoje, ap´os o t´ermino do hor´ario da eleic¸˜ao, ´e re-
movido de cada urna uma mem´oria contendo todos os votos realizados. Ap´os a remoc¸˜ao,
os respons´aveis pelas urnas se encaminham at´e uma sala espec´ıfica em cada local de
votac¸˜ao e, atrav´es de uma intranet enviam os dados da mem´oria para o servidor.
Para que pud´essemos simular esse mecanismo de envio de dados, optamos por
criar uma p´agina web. Atrav´es dessa p´agina, os demais grupos do PI, conseguem enviar
2 arquivos diferentes e selecionar o estado da federac¸˜ao. O primeiro arquivo que deve
ser selecionado na p´agina ´e referente aos candidatos que concorrem a vagas estaduais. O
segundo arquivo refere-se aos dados dos candidatos com os votos (Figure 1). Por fim,
para que seja poss´ıvel enviar os dados referentes `a urna, ´e preciso clicar no ´ıcone. O
tratamento, bem como, a organizac¸˜ao desses arquivos ser´a explicado posteriormente.
O visual da p´agina foi constru´ıdo atrav´es do uso do HTML5 e o framework Boot-
strap. Al´em disso, foi criado um pequeno ”mecanismo” visual de carregamento. Esse
”mecanismo” ´e ativado no momento em que o usu´ario clicar no ´ıcone da urna e, enquanto
´e feito o upload do arquivo o sistema apresentar´a esse carregamento.(Figure 2)
4.4. Desenvolvimento da tela web
Ap´os o design de a tela ter sido definido, foi preciso tornar a tela dinˆamica, de forma que,
ao clicar no ´ıcone para enviar os dados, a nossa aplicac¸˜ao pudesse receber os arquivos
de forma correta. Dito isso, usamos o micro framework Flask para que pudesse tornar
tal ac¸˜ao vi´avel. A organizac¸˜ao e estrutura das pastas ligadas a p´agina web pode ser vista
atrav´es da (Figure 6).
Atrav´es do uso de boas pr´aticas para programac¸˜ao de p´aginas web, deixamos
acess´ıvel ao usu´ario da tela, apenas o necess´ario e essencial, ou seja, todas as estruturas
de validac¸˜ao de formul´ario e a lista dos estados da federac¸˜ao (poss´ıvel ser visto atrav´es
do SELECT no formul´ario) est˜ao todos encapsulados no back-end.
4.5. Algoritmo de validac¸˜ao do arquivo
Para que n˜ao houvesse nenhum tipo de conflito entre os grupos na hora de gerar o arquivo
com os votos, criou-se um cabec¸alho padr˜ao para o arquivo com os dados dos candidatos
e o arquivo com os dados dos eleitores. O formato escolhido inicia-se com o n´umero 1
seguido do separador ’;’ na sequˆencia, ´e apresentado o t´ıtulo de cada coluna. O n´umero 1
representa o cabec¸alho e o n´umero 2 representa os dados (Figure 7) e (Figure 8).
No momento em que o usu´ario submete os arquivos, o sistema ir´a validar o ar-
quivo como um todo. Nesse momento, a primeira validac¸˜ao que ocorre, ´e com relac¸˜ao
a extens˜ao do arquivo. Caso o arquivo esteja em um formato diferente da extens˜ao .txt,
a aplicac¸˜ao ir´a retornar o status 401 e, consequentemente, ser´a apresentado na tela uma
mensagem de erro.
Caso n˜ao apresente nenhum problema com relac¸˜ao `a extens˜ao do arquivo, ser´a
feito ent˜ao, a leitura dos arquivos para identificar se ambos est˜ao no formato correto.
Nesse momento, ´e criado duas threads, um thread ser´a destinado `a validac¸˜ao do arquivo
do candidato e a outra respons´avel pelo arquivo do eleitor. O algoritmo para verificar se a
estrutura est´a de acordo com o informado ´e a mesma para ambos os arquivos. O algoritmo
criado faz a leitura apenas da primeira linha e, atrav´es do identificador ’;’ ´e separado cada
parte do cabec¸alho. Com a separac¸˜ao dos t´ıtulos ´e feita uma verificac¸˜ao um por um para
identificar se o t´ıtulo est´a correto ou n˜ao. Ao final, caso a estrutura de ambos os arquivos
estejam corretas, o arquivo ´e salvo de acordo com o nome do grupo informado e, ent˜ao,
seguir´a para a pr´oxima validac¸˜ao que ´e a do CPF de cada eleitor. Caso tenha algum
problema ao longo da verificac¸˜ao, ´e retornado o status 406 e apresentado uma mensagem
de erro na tela (Figure 4) e (Figure 5).
A validac¸˜ao do cabec¸alho ´e muito importante, uma vez que, caso o cabec¸alho
venha com os t´ıtulos na ordem trocada, ou at´e mesmo, com os nomes incorretos, a prob-
abilidade de que as linhas referentes aos votos ou os dados referentes aos candidatos
tamb´em estejam incorretos ´e bastante alta. Dessa forma, esse procedimento inicial de
validac¸˜ao tenta evitar problemas futuros na hora da validac¸˜ao do CPF e n´umero do can-
didato, bem como, na contabilizac¸˜ao dos votos.
A complexidade do algoritmo demonstrado acima ´e: O(N).
4.6. Algoritmo de validac¸˜ao de CPF
A validac¸˜ao do CPF de cada eleitor ´e feita ap´os a verificac¸˜ao dos arquivos enviados pelos
estados da federac¸˜ao. Nesse momento, foram desenvolvidos dois algoritmos na tentativa
de identificar o mais perform´atico, dessa forma, o primeiro foi feito usando a linguagem
de programac¸˜ao Python atrav´es de um simples FOR percorrendo linha por linha do ar-
quivo e passando os dados de cada linha para a func¸˜ao/m´etodo de verificac¸˜ao de CPF
(C´odigo 3).
A complexidade do algoritmo demonstrado acima ´e: O(N).
O segundo algoritmo desenvolvido, foi usando a API da Nvidia, o CUDA. A partir
desse momento, a complexidade no desenvolvimento da aplicac¸˜ao cresceu exponencial-
mente, ou seja, foi preciso entender muito bem o funcionamento dos blocos na placa de
v´ıdeo, bem como, a transferˆencia das informac¸˜oes do HOST para o DEVICE. Semelhante
ao algoritmo anterior ´e lido o dado de cada linha do arquivo atrav´es de um WHILE, nesse
momento, ´e feita as devidas alocac¸˜oes de cada linha em um vetor ´unico. Ap´os a alocac¸˜ao
de cada linha do arquivo enviado, ´e feita a preparac¸˜ao para o CUDA, ou seja, criamos os
ponteiros, bem como, suas alocac¸˜oes. Al´em disso, ´e feita a transferˆencia dos dados do
HOST para o DEVICE atrav´es da func¸˜ao cudaMemcpy (C´odigo 1).
Ap´os a transferˆencia dos dados para a placa de v´ıdeo, ´e definido o n´umero de blo-
cos que ser˜ao usados (C´odigo 2). Com o n´umero de blocos e a quantidade de threads
definidas, ´e feita ent˜ao a chamada da func¸˜ao valida (faz uso do paralelismo). Nessa
func¸˜ao, ´e feita a identificac¸˜ao do vetor dentro do bloco e, ap´os a identificac¸˜ao, para
cada linha ´e chamada a func¸˜ao respons´avel pela validac¸˜ao do CPF (C´odigo 3). Com a
validac¸˜ao finalizada, ´e feito a c´opia dos dados do DEVICE para o HOST. Por fim, caso a
aplicac¸˜ao identifique algum CPF inv´alido, ´e adicionado em um vetor de tamanho fixo de
10 posic¸˜oes, o n´umero da linha que cont´em o problema. No entanto, mesmo tendo lim-
itado o tamanho do vetor em 10 posic¸˜oes, n˜ao ´e poss´ıvel parar a execuc¸˜ao da validac¸˜ao,
pois como o arquivo ´e separado em diversos blocos, n˜ao ´e poss´ıvel saber quais ainda est˜ao
em execuc¸˜ao. Dito isso, ´e retornado para a tela as linhas referentes aos votos que pos-
suem problema com relac¸˜ao ao CPF (Figure 4). Caso n˜ao tenha problemas na validac¸˜ao,
´e encerrado esse procedimento e seguir´a para a pr´oxima validac¸˜ao.
A validac¸˜ao do CPF ´e de suma importˆancia para a aplicac¸˜ao, uma vez que, para
que um voto seja contabilizado de forma correta e v´alida, ´e preciso que o eleitor tenha um
CPF v´alido. Um detalhe importante a ser descrito, ´e que como as urnas eleitorais possuem
a funcionalidade de multiplicac¸˜ao dos votos, ou seja, ir´a ocorrer repetic¸˜ao dos CPF’s para
os diferentes votos, o servidor n˜ao faz uma validac¸˜ao de singularidade de voto.
Problemas encontrados pelo uso da abordagem acima:
• Uso de vari´aveis auxiliares:
– ´E muito comum ao longo da aplicac¸˜ao encontrar vari´aveis que sejam aux-
iliares. Dito isso, uma dessas vari´aveis ´e a ”idx”, ela ´e utilizada para
guardar os ´ındices. O problema no uso de uma vari´avel auxiliar utilizando
simultaneamente o processamento paralelo juntamente da API CUDA, ´e
que o processamento das linhas est´a ocorrendo de forma simultˆanea, ou
seja, pode ser que duas linhas apresentem erro simultaneamente e tentem
fazer uso do mesmo ´ındice, nesse momento, como est˜ao tentando acessar
a mesma vari´avel um erro ir´a sobrescrever o outro.
– Soluc¸˜ao: Como a programac¸˜ao em CUDA ´e feita atrav´es do uso da lin-
guagem C, encontramos uma palavra chave na linguagem chamada de
”register”. Os registers s˜ao mais r´apidos que as mem´orias de acesso,
dessa forma, como o pr´oprio nome sugere, s˜ao vari´aveis que ser˜ao ar-
mazenadas nos registradores e n˜ao nas mem´orias principais. Isso solu-
ciona uma parte do problema, pois agora o acesso `a mem´oria ´e feito de
forma muito mais r´apida. Al´em disso, usamos uma func¸˜ao da API CUDA
chamada de ”atomicAdd”, como as linhas s˜ao armazenadas em blocos den-
tro da placa de v´ıdeo, toda vez que uma linha ´e processada ´e usada a func¸˜ao
”atomicAdd” que ir´a realizar uma adic¸˜ao atˆomica a uma vari´avel (c´odigo
4).
• Vetor com o n´umero das linhas que contenham problemas no CPF:
– Como a aplicac¸˜ao foi criada para que fizesse uso do recurso de threads, ´e
poss´ıvel que durante a validac¸˜ao, dois CPF’s estejam inv´alidos simultane-
amente provocando na n˜ao ordenac¸˜ao das linhas, al´em disso, n˜ao ´e garan-
tido que ao enviar o mesmo arquivo com problemas de linhas inv´alidas, a
aplicac¸˜ao retorne as mesmas linhas. Isso ocorre novamente pelo uso dos
threads, pode ser que uma linha seja processada antes da outra e, nesse
momento, a linha a ser inserida no vetor seja diferente.
A complexidade do segundo algoritmo demonstrado acima ´e: O(N/1024).
1 CUDA_SAFE_CALL(cudaMalloc(&d_lines, next*sizeof(char)));
2 CUDA_SAFE_CALL(cudaMalloc(&d_ind, MAXLINES*sizeof(unsigned))
);
3 CUDA_SAFE_CALL(cudaMalloc(&d_lerror, 10*sizeof(int)));
4
5 CUDA_SAFE_CALL(cudaMemcpy(d_lerror, h_lerror, 10*sizeof(int)
, cudaMemcpyHostToDevice));
6 CUDA_SAFE_CALL(cudaMemcpy(d_lines, h_lines, next*sizeof(char
), cudaMemcpyHostToDevice));
7 CUDA_SAFE_CALL(cudaMemcpy(d_ind, ind, MAXLINES*sizeof(
unsigned), cudaMemcpyHostToDevice));
C´odigo 1 - Transferˆencia e alocac¸˜ao de mem´oria no CUDA.
1 // cont -> Quantidade de linhas do arquivo
2 // n_threads -> Valor fixo de 1024
3 int n_blocos = (cont + n_threads - 1) / n_threads;
C´odigo 2 - Definic¸˜ao da quantidade de blocos.
1 __device__ int validarCPF(char cpf[]) {
2 int i, j, digito1 = 0, digito2 = 0;
3 if(lenght(cpf) != 11)
4 return 1;
5 else if((compare(cpf,"00000000000", 11) == 0) || (compare(
cpf,"11111111111", 11) == 0) || (compare(cpf,"22222222222
", 11) == 0) ||
6 (compare(cpf,"33333333333", 11) == 0) || (compare(
cpf,"44444444444", 11) == 0) || (compare(cpf,"
55555555555", 11) == 0) ||
7 (compare(cpf,"66666666666", 11) == 0) || (compare(
cpf,"77777777777", 11) == 0) || (compare(cpf,"
88888888888", 11) == 0) ||
8 (compare(cpf,"99999999999", 11) == 0))
9 return 1; //se o CPF tiver todos os numeros iguais ele
invalido.
10 else {
11 //digito
1---------------------------------------------------
12 for(i = 0, j = 10; i < lenght(cpf)-2; i++, j--) //
multiplica os numeros de 10 a 2 e soma os resultados
dentro de digito1
13 digito1 += (cpf[i]-48) * j;
14 digito1 %= 11;
15 if(digito1 < 2)
16 digito1 = 0;
17 else
18 digito1 = 11 - digito1;
19 if((cpf[9]-48) != digito1)
20 return 1; //se o digito 1 no for o mesmo que o da
validao CPF invlido
21 else {
22 //digito
2--------------------------------------------------
23 for(i = 0, j = 11; i < lenght(cpf)-1; i++, j--) //
multiplica os numeros de 11 a 2 e soma os
resultados dentro de digito2
24 digito2 += (cpf[i]-48) * j;
25 digito2 %= 11;
26 if(digito2 < 2)
27 digito2 = 0;
28 else
29 digito2 = 11 - digito2;
30 if((cpf[10]-48) != digito2)
31 return 1; //se o digito 2 no for o mesmo que o
da validacao CPF invalido
32 }
33 }
34 return 0;
35 }
C´odigo 3 - Func¸˜ao/M´etodo - Validar CPF.
1 register int idx = atomicAdd(total, r);
C´odigo 4 - Exemplificac¸˜ao do uso da palavra chave register e uso da func¸˜ao atomicAdd.
4.7. Algoritmo de validac¸˜ao da Regi˜ao
Para a validac¸˜ao da Regi˜ao pensamos em dois algoritmos diferentes que iriam atender
o nosso prop´osito, no entanto, umas das abordagens que tentamos n˜ao funcionou
corretamente e ser´a descrito mais a frente o porque de n˜ao ter dado certo. A abordagem
que desenvolvemos ´e semelhante a validac¸˜ao do cabec¸alho. Inicialmente criamos uma
lista no Python contendo o grupo de estados referentes a cada grupo, segue a lista:
Grupo A: [’PR’,’SC’,’RS’];
Grupo B: [’RN’,’CE’,’PI’];
Grupo C: [’ES’,’BA’,’SE’];
Grupo D: [’AL’,’PE’,’PB’];
Grupo E: [’SP’,’MG’,’RJ’];
Grupo F: [’MA’,’AP’,’PA’];
Grupo G: [’AM’,’AC’,’RR’];
Grupo H: [’DF’,’GO’,’MS’];
Grupo I: [’MT’,’TO’,’RO’].
Ap´os a lista ter sido definida, criamos uma func¸˜ao (c´odigo 5) que ir´a retornar para
um vetor o valor em decimal do estado. Esse valor pode ser consultado atrav´es da tabela
ASCII. Com os valores dentro do vetor, ´e feita a alocac¸˜ao do vetor na mem´oria da placa
de v´ıdeo, assim como na validac¸˜ao do CPF. Ap´os a alocac¸˜ao, ´e enviado para o m´etodo
”valida” todas as informac¸˜oes necess´arias para a validac¸˜ao.
Dentro da func¸˜ao ”valida”, criamos um lac¸o de repetic¸˜ao respons´avel por com-
parar o valor em decimal apresentado pela linha com a lista que criamos anteriormente.
Caso esteja sem nenhum problema na linha vai para o pr´oximo ´ındice, caso algum ´ındice
apresente problema, para que exista uma separac¸˜ao entre problema com o CPF e problema
com o estado, adicionamos o valor da linha com problema com o seu valor negativo.
Com relac¸˜ao a primeira abordagem que ir´ıamos seguir, tentamos criar um vetor e
conforme ´ıamos percorrendo as linhas, verificav´amos se o estado j´a havia sido preenchido
ou n˜ao, caso n˜ao estivesse no vetor inser´ıamos ele, caso j´a estivesse, prosseguimos com
a validac¸˜ao. O problema dessa abordagem j´a foi mencionada anteirormente, como a
aplicac¸˜ao est´a fazendo uso do processamento paralelo, duas linhas distintas tentavam
acessar simultaneamente o mesmo ´ındice do vetor, no entanto, para essa abordagem n˜ao
conseguimos solucionar o problema fazendo uso dos ”registers” ou atomicAdd. Al´em
disso, o desenvolvimento do primeiro algoritmo citado, funcionou muito bem com a nossa
aplicac¸˜ao, dessa forma, optamos por n˜ao prosseguir com essa metodologia.
A complexidade do segundo algoritmo demonstrado acima ´e: O(N/1024).
1 for(int i=0; i<6; i++)
2 h_state[i] = (int)PyFloat_AsDouble(PyList_GetItem(
state_list, i));
C´odigo 5 - Convers˜ao da lista em Pyhon para valor em decimal referente ao estado.
4.8. Algoritmo de contagem dos votos
O procedimento inicial para o desenvolvimento do algoritmo respons´avel pela contagem
dos votos ´e um pouco parecido com o algoritmo de validac¸˜ao do CPF. Para que fosse
poss´ıvel a implementac¸˜ao, utilizamos o processamento paralelo juntamente do processa-
mento dos dados na placa de v´ıdeo (API CUDA).
Ap´os todas as validac¸˜oes terem sido efetuadas com sucesso, a contagem dos vo-
tos dos candidatos federais entra em ac¸˜ao. ´E feita a leitura do arquivo chamado presi-
dentes.txt, que possu´ı a estrutura referente a imagem (Figure 7), essa leitura ´e feita atrav´es
da linguagem de programac¸˜ao Python e, ent˜ao, ´e criada uma lista contendo o nome do
candidato juntamente do seu c´odigo, ap´os a lista ter sido definida, ´e enviado por meio da
API de integrac¸˜ao entre Python e o C essa lista (c´odigo 6). Ap´os a convers˜ao, ´e feita a
alocac¸˜ao da vari´avel e c´opia da variv´avel auxiliar na mem´oria da placa de v´ıdeo (c´odigo
7).
Com todo o estado da placa de v´ıdeo pronto e preparado para iniciar o processa-
mento, ´e acionada a func¸˜ao ”valida”. Na func¸˜ao valida ´e feito inicialmente a validac¸˜ao da
Regi˜ao e posteriormente do CPF e logo em seguida entra a func¸˜ao respons´avel por fazer a
comprac¸˜ao da lista dos candidatos enviada para a placa de v´ıdeo e o dado que est´a na linha
do arquivo. Como o tamanho do campo ”c´odigo do candidato” ´e fixado em 2 posic¸˜oes, ´e
criada uma vari´avel que ir´a armazenar em posic¸˜oes distintas do vetor cada valor do dado.
Com os valores definidos, ´e feita a convers˜ao dos caracteres e, ent˜ao, estar´a pronto para
passar por um lac¸o de repetic¸˜ao varrendo a lista dos candidatos poss´ıveis e incrementando
o vetor de resultados de cada candidato, uma vez que, ´e feita a paridade entre os c´odigos.
Problemas encontrados pelo uso da abordagem acima:
• Convers˜ao do c´odigo do candidato do arquivo para inteiro:
– Quando chegamos no momento de realizar a comparac¸˜ao entre os c´odigos
dos candidatos que foram enviados para a placa de v´ıdeo e o valor do
candidato presente no arquivo n˜ao sabiamos como iria ser feita essa
comparac¸˜ao, pois o dado que ´e extra´ıdo do arquivo vem em formato de
um vetor de strings, nesse momento, pensamos em realizar a convers˜ao do
valor do caracter para bin´ario, no entanto, essa abordagem n˜ao funcionaria,
uma vez que, o valor em bin´ario do caracter ’9’ ´e diferente do valor em
bin´ario do n´umero 9. Como essa m´etodo descrito n˜ao funcionaria, pen-
samos em criar no Python a lista com os valores em string ao inv´es de
valor inteiro, no entanto, quando fossˆemos retornar o vetor de resultados
com os valores em string teriamos problemas em realizar a contabilizac¸˜ao
total. Por fim, encontramos a soluc¸˜ao que ´e descrita no (c´odigo 8) que
funciona perfeitamente para a nossa proposta.
A complexidade do segundo algoritmo demonstrado acima ´e: O(N/1024).
1 // Candidato
2 int size_tt = PyList_Size(state_list);
3
4 int h_cd[size_tt-6];
5 int h_aux_cd[size_tt-6];
6 int resultado[size_tt-6];
7 int idx_cd = 0;
8
9 for(int i=0; i<size_tt; i++){
10 if(i < 6)
11 h_state[i] = (int)PyFloat_AsDouble(PyList_GetItem(
state_list, i));
12 else{
13 // Candidatos
14 h_cd[idx_cd] = (int)PyFloat_AsDouble(PyList_GetItem(
state_list, i));
15 h_aux_cd[idx_cd] = 0;
16 resultado[idx_cd++] = 0;
17 }
18 }
C´odigo 6 - Convers˜ao da lista em Python.
1 CUDA_SAFE_CALL(cudaMalloc(&d_aux_cd, (size_tt-6)*sizeof(int)
));
2 CUDA_SAFE_CALL(cudaMemcpy(d_aux_cd, h_aux_cd, (size_tt-6)*
sizeof(int), cudaMemcpyHostToDevice));
C´odigo 7 - Alocac¸˜ao e c´opia da vari´avel para a placa de v´ıdeo.
1 char cd_federal[2];
2
3 cd_federal[0] = string[cont];
4 cont++;
5 cd_federal[1] = string[cont];
6
7 int cod = (cd_federal[0] - ’0’)*10 + (cd_federal[1] - ’0’);
C´odigo 8 - Convers˜ao dos valores da linha.
4.9. Fila de processamento
Ap´os todos os passos descritos acima, optamos por implementar um mecanismo de fila
de processamento. Desenvolvemos a fila com o intuito de evitar que dois grupos envi-
assem o arquivo para o servidor de forma simultˆanea e ocasionasse em algum problema
no processamento. Dito isso, a fila funciona da seguinte forma: no momento em que a
aplicac¸˜ao ´e iniciada o job respons´avel por ficar verificando se existe algum arquivo para
validar ou n˜ao ´e acionado. Quando um grupo submete um arquivo para a validac¸˜ao e
contagem dos votos, esse arquivo ´e armazenado em um diret´orio chamado de ”n˜ao val-
idado”, o job fica verificando esse diret´orio a procura de arquivos para serem validados,
caso encontre algum arquivo no diret´orio, o job ir´a enviar o arquivo para os fluxos de
validac¸˜ao e contagem. Caso um grupo tente reenviar um arquivo que ainda est´a na fila
para ser processado, retornamos uma mensagem de erro na tela (Figure 11).
5. Experimentos e An´alise dos Resultados
Nessa sec¸˜ao apresentamos os resultados obtidos pela aplicac¸˜ao de acordo com cada
implementac¸˜ao, bem como, os tipos de experimentos que realizamos com o intuito de
chegarmos a uma conclus˜ao plaus´ıvel com relac¸˜ao aos resultados.
Os testes foram realizados utilizando a aplicac¸˜ao feita em CUDA (processamento
paralelo, integrac¸˜ao de linguagens, utilizac¸˜ao de processamento dentro da placa de v´ıdeo)
e tamb´em realizada no Python (utilizac¸˜ao de threads). Os testes n˜ao levam em conta o
tempo que a aplicac¸˜ao leva para receber o arquivo (upload), apenas o tempo que leva para
executar os processos de validac¸˜ao e contagem. Os testes realizados foram feitos para
um total de cem, mil, dez mil, cem mil, um milh˜ao, dez milh˜oes e sessenta milh˜oes de
linhas.we
Atrav´es da an´alise das imagens (Figure 9) e (Figure 10) ´e poss´ıvel chegar a con-
clus˜ao de que a utilizac¸˜ao do CUDA para uma massa de testes de at´e dez mil linhas n˜ao
´e vi´avel, acima desse valor, o CUDA ´e extremamente recomend´avel, pois a perfomance
adquirida ´e muito superior quando comparado com o Python. A maior discrepˆancia pode
ser vista ao validar e contabilizar os votos de um arquivo de sessenta milh˜oes de lin-
has, enquanto o CUDA realizou o processamento em aproximadamente dez segundos, o
Python levou em torno de 40 minutos.
Observac¸˜ao.: O experimento foi realizado em uma m´aquina com as seguintes
configurac¸˜oes:
• Processador: I7 7700 3.6 GHz
• Placa de V´ıdeo: GTX 1060 6GB 8008MHz
• Mem´oria Ram: 2x8gb ram 2400MHz
6. Conclus˜ao e Trabalhos Futuros
Diante deste estudo/desenvolvimento de algoritmos com o intuito de comparar os resul-
tados da aplicac¸˜ao em cada tecnologia, o uso da API CUDA juntamente do recurso com-
putacional de programac¸˜ao paralela mostrou-se mais efetivo e eficaz para valores muito
altos. Quando comparados com valores muito pequenos, uma abordagem padr˜ao como
por exemplo, o uso de linguagem C ou Python, ´e mais efetivo.
Com base nos argumentos apresentados, o projeto integrador proposto vai ao en-
contro do que foi apresentado nas motivac¸˜oes iniciais. Sendo assim, conclu´ımos que ´e
preciso realizar diversos experimentos at´e que seja comprovada a efic´acia do algoritmo,
bem como, o recurso computacional.
Atrav´es dos resultados expressos na sec¸˜ao anterior ´e poss´ıvel identificar todas as
comparac¸˜oes realizadas e, a partir delas, escolher uma poss´ıvel abordagem de acordo com
a sua aplicac¸˜ao.
Como sugest˜oes de poss´ıveis trabalhos futuros, pode-se apontar a implementac¸˜ao
de novos recursos, tais como:
• Implementac¸˜ao de novo algoritmo respons´avel pela validac¸˜ao dos candidato;
• Uso de inteligˆencia artif´ıcial com o objetivo de extrair e identificar as informac¸˜oes
extras enviadas pelos grupos;
• Implementac¸˜ao de novo algoritmo respons´avel pela contabilizac¸˜ao dos votos dos
candidatos estaduais;
• Implementac¸˜ao de novo algoritmo respons´avel pela an´alise do resultado dos votos,
ou seja, separac¸˜ao de votos por estados, classe econˆomica.
7. Referˆencia
Segue abaixo as referˆencias usadas ao longo da montagem do artigo/aplicac¸˜ao.
References
Ferlin, E. P. (2011). In O que ´e Processamento Paralelo? -
http://professorferlin.blogspot.com/2011/08/o-que-e-processamento-paralelo.html.
Flask. In Flask Documentation. Flask 1.0 edition.
Microsoft. In Visual Studio Code - https://code.visualstudio.com/.
Nvidia. In CUDA Toolkit Documentation. 10.0.130 edition.
Schildt, H. (1996). In C - Completo e Total, pages 15–20. Makron Books, 3th edition.
Tanenbaum, A. S. (2015). In Sistemas Operacionais Modernos, pages 50–87. S˜ao Paulo,
3th edition.
TensorFlow. In Tensor Flow - https://www.tensorflow.org.
TSE. In Tribunal Superior Eleitoral - http://www.tse.jus.br/.
Tulchak, L. V. and Marchuk, O. A. O. In History of Python, pages 1–3. 1th edition.
8. Imagens
Figure 1. Prot´otipo da tela
Figure 2. Carregamento da tela
Figure 3. Arquivo Enviado com Sucesso
Figure 4. Arquivo Inv´alido - problema com CPF
Figure 5. Arquivo Inv´alido - problema com estado
Figure 6. Estrutura das pastas - Interface Web
Figure 7. Modelo do cabec¸alho - Candidatos
Figure 8. Modelo do cabec¸alho - Eleitores
Figure 9. Tempo de processamento em segundos
Figure 10. Preenchimento de ´areas em segundos
Figure 11. Erro reportado ao tentar inserir um novo arquivo para processar que
j´a est´a na fila

Mais conteúdo relacionado

Semelhante a Servidor com processamento paralelo utilizando CUDA aplicado em uma urna eletrônica

Big data para programadores convencionais
Big data para programadores convencionaisBig data para programadores convencionais
Big data para programadores convencionaisRoberto Oliveira
 
Artigo - PROJETO DE UM HARDWARE ACELERADOR DO ALGORITMO DE DISTÂNCIA EUCLIDIA...
Artigo - PROJETO DE UM HARDWARE ACELERADOR DO ALGORITMO DE DISTÂNCIA EUCLIDIA...Artigo - PROJETO DE UM HARDWARE ACELERADOR DO ALGORITMO DE DISTÂNCIA EUCLIDIA...
Artigo - PROJETO DE UM HARDWARE ACELERADOR DO ALGORITMO DE DISTÂNCIA EUCLIDIA...GiovanniGuimares2
 
Projeto Indiana
Projeto IndianaProjeto Indiana
Projeto Indianahellequin
 
plano_de_projeto_controlart_final
plano_de_projeto_controlart_finalplano_de_projeto_controlart_final
plano_de_projeto_controlart_finaluserrx
 
Plano de projeto de software - SISCONI
Plano de projeto de software - SISCONIPlano de projeto de software - SISCONI
Plano de projeto de software - SISCONIocfelipe
 
3º Apresentação Intercalar
3º Apresentação Intercalar3º Apresentação Intercalar
3º Apresentação IntercalarGrupo3ProjBliblio
 
Plano do projeto de software
Plano do projeto de softwarePlano do projeto de software
Plano do projeto de softwareDanilo Gois
 
Plano de projeto de software - SISCONI
Plano de projeto de software - SISCONIPlano de projeto de software - SISCONI
Plano de projeto de software - SISCONIocfelipe
 
Relatório técnico sobre Ferramentas de Planos de Gestão de Dados - Jornadas d...
Relatório técnico sobre Ferramentas de Planos de Gestão de Dados - Jornadas d...Relatório técnico sobre Ferramentas de Planos de Gestão de Dados - Jornadas d...
Relatório técnico sobre Ferramentas de Planos de Gestão de Dados - Jornadas d...Pedro Príncipe
 
[MTC 2021] As 8 melhores práticas e formas de simplificar e estruturar todos...
[MTC 2021] As 8 melhores práticas e formas de simplificar e estruturar todos...[MTC 2021] As 8 melhores práticas e formas de simplificar e estruturar todos...
[MTC 2021] As 8 melhores práticas e formas de simplificar e estruturar todos...minastestingconference
 
BIODATA: SOFTWARE WEB PARA GERENCIAMENTO DE COLETA DE DADOS BIOMÉDICOS
BIODATA: SOFTWARE WEB PARA GERENCIAMENTO DE COLETA DE DADOS BIOMÉDICOSBIODATA: SOFTWARE WEB PARA GERENCIAMENTO DE COLETA DE DADOS BIOMÉDICOS
BIODATA: SOFTWARE WEB PARA GERENCIAMENTO DE COLETA DE DADOS BIOMÉDICOSAdilmar Dantas
 
Planejamento e Gerenciamento de Capacidade para Sistemas Distribuídos
Planejamento e Gerenciamento de Capacidade para Sistemas DistribuídosPlanejamento e Gerenciamento de Capacidade para Sistemas Distribuídos
Planejamento e Gerenciamento de Capacidade para Sistemas Distribuídosluanrjesus
 
Projeto de Software - PIC Eletrônico - Gerência de Projetos UFAM 2012/2
Projeto de Software - PIC Eletrônico - Gerência de Projetos UFAM 2012/2Projeto de Software - PIC Eletrônico - Gerência de Projetos UFAM 2012/2
Projeto de Software - PIC Eletrônico - Gerência de Projetos UFAM 2012/2Urique Hoffmann
 
Configuração de ativos de rede utilizando a abordagem infrastructure as code
Configuração de ativos de rede utilizando a abordagem infrastructure as codeConfiguração de ativos de rede utilizando a abordagem infrastructure as code
Configuração de ativos de rede utilizando a abordagem infrastructure as codeAécio Pires
 

Semelhante a Servidor com processamento paralelo utilizando CUDA aplicado em uma urna eletrônica (20)

Trabalho PI I
Trabalho PI ITrabalho PI I
Trabalho PI I
 
Big data para programadores convencionais
Big data para programadores convencionaisBig data para programadores convencionais
Big data para programadores convencionais
 
Artigo - PROJETO DE UM HARDWARE ACELERADOR DO ALGORITMO DE DISTÂNCIA EUCLIDIA...
Artigo - PROJETO DE UM HARDWARE ACELERADOR DO ALGORITMO DE DISTÂNCIA EUCLIDIA...Artigo - PROJETO DE UM HARDWARE ACELERADOR DO ALGORITMO DE DISTÂNCIA EUCLIDIA...
Artigo - PROJETO DE UM HARDWARE ACELERADOR DO ALGORITMO DE DISTÂNCIA EUCLIDIA...
 
Projeto Indiana
Projeto IndianaProjeto Indiana
Projeto Indiana
 
portfolio unopar
portfolio unoparportfolio unopar
portfolio unopar
 
plano_de_projeto_controlart_final
plano_de_projeto_controlart_finalplano_de_projeto_controlart_final
plano_de_projeto_controlart_final
 
Dfd
DfdDfd
Dfd
 
Plano de projeto de software - SISCONI
Plano de projeto de software - SISCONIPlano de projeto de software - SISCONI
Plano de projeto de software - SISCONI
 
3º Apresentação Intercalar
3º Apresentação Intercalar3º Apresentação Intercalar
3º Apresentação Intercalar
 
Plano do projeto de software
Plano do projeto de softwarePlano do projeto de software
Plano do projeto de software
 
EXERCÍCIOS 01.pdf
EXERCÍCIOS 01.pdfEXERCÍCIOS 01.pdf
EXERCÍCIOS 01.pdf
 
Plano de projeto de software - SISCONI
Plano de projeto de software - SISCONIPlano de projeto de software - SISCONI
Plano de projeto de software - SISCONI
 
Relatório técnico sobre Ferramentas de Planos de Gestão de Dados - Jornadas d...
Relatório técnico sobre Ferramentas de Planos de Gestão de Dados - Jornadas d...Relatório técnico sobre Ferramentas de Planos de Gestão de Dados - Jornadas d...
Relatório técnico sobre Ferramentas de Planos de Gestão de Dados - Jornadas d...
 
[MTC 2021] As 8 melhores práticas e formas de simplificar e estruturar todos...
[MTC 2021] As 8 melhores práticas e formas de simplificar e estruturar todos...[MTC 2021] As 8 melhores práticas e formas de simplificar e estruturar todos...
[MTC 2021] As 8 melhores práticas e formas de simplificar e estruturar todos...
 
BIODATA: SOFTWARE WEB PARA GERENCIAMENTO DE COLETA DE DADOS BIOMÉDICOS
BIODATA: SOFTWARE WEB PARA GERENCIAMENTO DE COLETA DE DADOS BIOMÉDICOSBIODATA: SOFTWARE WEB PARA GERENCIAMENTO DE COLETA DE DADOS BIOMÉDICOS
BIODATA: SOFTWARE WEB PARA GERENCIAMENTO DE COLETA DE DADOS BIOMÉDICOS
 
Asa cpbr4
Asa cpbr4Asa cpbr4
Asa cpbr4
 
Globus Toolkit
Globus ToolkitGlobus Toolkit
Globus Toolkit
 
Planejamento e Gerenciamento de Capacidade para Sistemas Distribuídos
Planejamento e Gerenciamento de Capacidade para Sistemas DistribuídosPlanejamento e Gerenciamento de Capacidade para Sistemas Distribuídos
Planejamento e Gerenciamento de Capacidade para Sistemas Distribuídos
 
Projeto de Software - PIC Eletrônico - Gerência de Projetos UFAM 2012/2
Projeto de Software - PIC Eletrônico - Gerência de Projetos UFAM 2012/2Projeto de Software - PIC Eletrônico - Gerência de Projetos UFAM 2012/2
Projeto de Software - PIC Eletrônico - Gerência de Projetos UFAM 2012/2
 
Configuração de ativos de rede utilizando a abordagem infrastructure as code
Configuração de ativos de rede utilizando a abordagem infrastructure as codeConfiguração de ativos de rede utilizando a abordagem infrastructure as code
Configuração de ativos de rede utilizando a abordagem infrastructure as code
 

Servidor com processamento paralelo utilizando CUDA aplicado em uma urna eletrônica

  • 1. Servidor com processamento paralelo utilizando CUDA aplicado em uma urna eletrˆonica Douglas A. Cunha1 , Rafael R. P. Araujo2 1 Centro Universit´ario IESB CEP: 70.200-730 – Bras´ılia – DF – Brazil 2 Ciˆencia da Computac¸˜ao – Centro Universit´ario IESB Bras´ılia, Brazil {douglasxxdouglas,bsb.rafaelaraujo}@gmail.com Abstract. The present research aims to identify and develop through the integration of the companies analyzed, a set of valid data, count and manipulate the data sent by each state of the federation. The study, looked for more profitable algorithms, since, the value of stresses was of 1 billion of registries. For the development of the work several technologies were used, in particular, a programming language for the decision making on the ability to optimize the time for the validation as the counting of votes through the parallelism and use of the video card as processing source. The reflection of the research, turned into the algorithms developed and tested in the most diverse languages, the most perfomatic CUDA was used. In addition, it was possible to obtain a final count of the votes of the election. Keywords: CUDA. Server. Validation. Resumo. A presente pesquisa visa identificar e desenvolver atrav´es da integrac¸˜ao das mat´erias anteriormente estudadas, um servidor capaz de validar, contar e manipular os dados enviados por cada estado da federac¸˜ao. O estudo buscou identificar os algoritmos mais perform´aticos, uma vez que, o valor de estresse estipulado foi de um bilh˜ao de registros. Para o desen- volvimento do trabalho foram utilizadas diversas tecnologias, em especial, a linguagem de programac¸˜ao CUDA para que fosse poss´ıvel aperfeic¸oar/otimizar o tempo tanto de validac¸˜ao como de contagem de votos atrav´es do paralelismo e uso da placa de v´ıdeo como fonte processadora. O reflexo da pesquisa mostrou que dentre os diversos algoritmos desenvolvidos e testados nas mais diversas linguagens, o mais perform´atico foi utilizando CUDA. Al´em disso, foi poss´ıvel obter a contagem final dos votos da eleic¸˜ao. Palavras-chave: CUDA. Servidor. Validac¸˜ao. 1. Siglas • ANSI - American National Standard Institute • API - Interface de Programac¸˜ao de Aplicac¸˜ao • BSD - Berkeley Software Distribution • CPU - Unidade Central de Processamento
  • 2. • GPGPU - A Unidade de Processamento Gr´afico de Prop´osito Geral • GPU - Unidade de Processamento Gr´afico • ISA’s - Instruction Set Architecture • RAM - Mem´oria de Acesso Aleat´orio • WSGI - Interface de Porta de Entrada do Servidor Web • HTML - HyperText Markup Language • CSS - Cascading Style Sheets 2. Introduc¸˜ao A cada quatro anos ´e realizado por todo o pa´ıs uma eleic¸˜ao com o intuito de escolher candidatos que ir˜ao governar durante um determinado per´ıodo de tempo. Dessa forma, ap´os muitos anos a forma de apurac¸˜ao dos votos serem utilizadas atrav´es de papeis e contados por pessoas, criou-se o atual sistema e mecanismo de voto, o coletor eletrˆonico de voto. O coletor eletrˆonico de voto, tamb´em conhecido como urna eletrˆonica, ´e uma m´aquina/mecanismo de votac¸˜ao que ir´a registrar os votos dos eleitores em mem´orias in- ternas que posteriormente ser˜ao enviadas para um terminal. Nos centros urbanos, em cada local de votac¸˜ao tem um terminal de acesso ao sistema interno da Justic¸a Eleitoral. Atrav´es dessa rede que as informac¸˜oes referentes a cada urna ser˜ao enviadas para o Tribunal Regional Eleitoral de cada estado da federac¸˜ao. Essas informac¸˜oes s˜ao transmitidas atrav´es de uma estrutura de comunicac¸˜ao pr´opria que ´e fornecida pelas operadoras de telefonia. Dessa forma, ap´os o fim do hor´ario eleitoral, os locais ir˜ao se conectar atrav´es de uma intranet (rede privada), pela qual as informac¸˜oes ser˜ao transmitidas. [TSE ] Com as informac¸˜oes no servidor referente a cada urna eletrˆonica, o mesmo comec¸a a contagem e processamento dos dados fornecendo ao final, o candidato eleito. No en- tanto, apesar de possuir especialistas e pessoas extremamente capacitadas que cuidam e desenvolvem algoritmos e processos inteligentes e r´apidos, algumas abordagens podem passar despercebidas ou at´e mesmo ignoradas. Dessa forma, o presente artigo ir´a abordar diversos algoritmos testados at´e que cheg´assemos ao resultado final mais perform´atico com relac¸˜ao `a validac¸˜ao, contagem e processamento desses dados. 2.1. Motivac¸˜ao O n´umero de trabalhos relacionados a algoritmos de estrutura de dados aplicados `a uma urna ´e bastante reduzido, dessa forma, com a motivac¸˜ao de contribuir para que a comu- nidade tenha acesso a diferentes modelos e sistemas de urna eleitoral, foi desenvolvido o presente artigo. Al´em disso, o assunto abordado foi motivado e incentivado por nosso orientador. Por fim, o poder computacional proposto no presente artigo nos motivou ainda mais em prosseguir com a ideia de usar processamento paralelo e CUDA. 2.2. Hip´otese Antes de se iniciar o desenvolvimento do servidor, conversamos sobre qual abordagem ir´ıamos seguir, bem como, os poss´ıveis resultados esperados. No entanto, no decorrer do desenvolvimento do projeto, fomos encontrando pontos e indicativos de que as estrat´egias adotadas n˜ao seriam as melhores, esses indicativos foram poss´ıveis de serem vistos, uma
  • 3. vez que, a quantidade de linhas que teriam de ser processadas, bem como, a quantidade de arquivos recebidos simultaneamente precisaria de um poder computacional muito grande e atrav´es do uso de recursos mais simples isso n˜ao seria poss´ıvel. Para resolvermos o problema utilizamos a integrac¸˜ao entre duas linguagens (C e Python) realizando o proces- samento atrav´es da placa de v´ıdeo e o processamento paralelo. 2.3. Objetivos e Desafios da Pesquisa Durante a pesquisa e desenvolvimento do presente artigo, alguns desafios tiveram de ser enfrentados, dentre eles a demora em gerar massas de testes, a limitac¸˜ao da mem´oria RAM dos nossos computadores pessoais dificultando na leitura de grande quantidade de linhas, a necessidade de integrac¸˜ao de duas linguagens distintas (Python e C) e do estudo/implemenac¸˜ao do CUDA. Al´em disso, como a comunidade do CUDA ainda ´e pequena, ent˜ao, as soluc¸˜oes para alguns problemas s˜ao bastante complexas e dif´ıceis de serem encontradas, dessa forma, por vezes ficamos impossibilitados de prosseguir no desenvolvimento tendo de procurar outras sa´ıdas e soluc¸˜oes. A an´alise da complexidade dos algoritmos tamb´em se tornou um desafio ao longo da pesquisa. • Objetivo Geral – Produc¸˜ao de um servidor respons´avel pela manipulac¸˜ao, validac¸˜ao e con- tagem dos votos enviados por cada estado da federac¸˜ao. • Objetivos espec´ıficos – Analisar os tempos de execuc¸˜ao de cada algoritmo desenvolvido; – Comparar as diferentes tecnologias com a finalidade de encontrar a que oferece melhor desempenho de acordo com o objetivo geral proposto. 2.4. Contribuic¸˜oes O presente artigo ir´a contribuir para testar a integralidade dos arquivos. Al´em disso, o nosso trabalho contribuir´a para a contabilizac¸˜ao total dos votos da eleic¸˜ao simulada, tamb´em ser´a poss´ıvel extrair atrav´es desse trabalho, diferentes algoritmos que poder˜ao ser utilizados para o estudo da mat´eria estrutura de dados. O presente artigo poder´a contribuir no desenvolvimento de outras aplicac¸˜oes que fazem uso da API CUDA, uma vez que, a comunidade do CUDA ´e bastante reduzida, a publicac¸˜ao desse artigo poderia ajudar as pessoas a criarem suas pr´oprias aplicac¸˜oes/projetos. 2.5. Organizac¸˜ao da Dissertac¸˜ao O trabalho est´a dividido em cinco cap´ıtulos, os quais se descrevem resumidamente a seguir: • Sec¸˜ao 2 – Introduc¸˜ao: aborda a motivac¸˜ao, objetivos e desafios da pesquisa, hip´otese, contribuic¸˜oes e organizac¸˜ao da dissertac¸˜ao. • Sec¸˜ao 3 – Fundamentac¸˜ao Te´orica: aborda a fundamentac¸˜ao te´orica das tecnolo- gias usadas e os trabalhos correlatos. • Sec¸˜ao 4 – Proposta e Desenvolvimento: apresenta a proposta da pesquisa, bem como, os passos do desenvolvimento do servidor. • Sec¸˜ao 5 – Experimentos e An´alise dos Resultados: apresenta a metodologia usada, experimentos e a avaliac¸˜ao dos resultados. • Sec¸˜ao 6 – Conclus˜ao e Trabalhos Futuros: s˜ao feitas as considerac¸˜oes finais, al´em das propostas de trabalhos futuros.
  • 4. • Sec¸˜ao 7 – Referˆencias: referˆencias usadas ao longo do desenvolvimento do pre- sente artigo, bem como, no desenvolvimento da aplicac¸˜ao. • Sec¸˜ao 8 – Imagens: imagens usadas no presente artigo. 3. Fundamentac¸˜ao Te´orica 3.1. Tecnologias Para que fosse poss´ıvel o desenvolvimento do servidor, foram utilizadas as seguintes tec- nologias: • Editor de C´odigo Fonte: – Visual Studio Code • Linguagens de programac¸˜ao: – C – Python • API: – CUDA • Framework: – Flask • Recursos Computacionais: – Processamento Paralelo – Processamento Paralelo com API CUDA. 3.2. Editor de C´odigo Fonte Visual Studio Code O editor de c´odigo-fonte foi desenvolvido em 2015 pela Microsoft para Windows, Linux e macOS, o mesmo inclu´ı suporte para depurac¸˜ao, controle do GIT incorporado, realce de sintaxe, complementac¸˜ao de c´odigo, snippets e refatorac¸˜ao de c´odigo. O Visual Studio Code ´e baseado no Electron, um framework usado para desenvolver aplicativos Node.js para o desktop rodando no motor de layout blink. A decis˜ao da escolha pela IDE levou em conta a compatibilidade com as linguagens que foram usadas no projeto, bem como, a inteligˆencia da mesma para refatorac¸˜ao de c´odigos quando necess´ario, al´em disso, do baixo consumo de recursos computacionais durante o uso. [Microsoft ] 3.3. Linguagem de Programac¸˜ao C A linguagem de programac¸˜ao C foi criada por volta dos anos 70 e implementada em um computador nomeado de DEC PDP-11 por Dennis Ritchie. O C tem sua origem a partir de outras duas linguagens: Algol 68 e BCPL. Inicialmente o uso da linguagem era destinado ao desenvolvimento de sistemas operacionais e compiladores. Essa linguagem foi usada na construc¸˜ao de uma nova vers˜ao do sistema operacional Unix, que inicialmente, foi escrito em Assembly. Com o grande sucesso desse desenvolvimento, a linguagem ganhou mais adeptos e, portanto, nos dias atuais, a maiora todos os grandes sistemas operacionais s˜ao constru´ıdos em C. Apesar de todos os esforc¸os e a grande quantidade de usu´arios fazendo uso da linguagem, ela ainda n˜ao era uma linguagem padronizada. Por volta dos anos 80 o C j´a contava com uma gama de compiladores, no entanto, apesar do grande n´umero ainda ex- istiam diversas diferenc¸as ocasionando na incompatibilidade entre eles. Nesse momento, a padronizac¸˜ao da linguagem foi iniciada em 1983 pela ANSI e finalizada em 1989.
  • 5. Utilizaremos a linguagem C, pois como a mesma ´e uma linguagem de proposito geral, ou seja, a adaptabilidade na maioria dos projetos ´e extremamente alta. No entanto, um segundo e mais importante ponto que analisamos para realizar a escolha foi a sua velocidade em tempo de execuc¸˜ao. O C diferente de outras linguagens ´e extremamente r´apido em tempo de execuc¸˜ao devido `a arquitetura em que foi desenvolvida. Isso ocorre, pois linguagens como Java, Basic, Perl, dentre outras s˜ao linguagens a base de byte- code interpretados por uma m´aquina virtual, enquanto no C, a interpretac¸˜ao do c´odigo ´e realizada diretamente pelo processador. Al´em disso, atrav´es do C ´e poss´ıvel realizar enderec¸amentos de mem´oria de maneira bastante parecida como ´e feito em Assembly. Dessa forma, em aplicac¸˜oes que exigem tarefas de baixo-n´ıvel, ou seja, que ne- cessitam do acesso direto a mem´oria, como por exemplo, a c´opia de bytes para uma placa de rede ou de v´ıdeo, s´o ´e poss´ıvel atrav´es do C. Por fim, o C permite a personalizac¸˜ao de diversos algoritmos pr´e-implementados, como por exemplo, a alocac¸˜ao de mem´oria, com o objetivo de melhorar o desempenho ou at´e mesmo adaptar de acordo com a sua necessidade.[Schildt 1996] 3.4. Linguagem de Programac¸˜ao Python A linguagem de programac¸˜ao Python foi criada por volta dos anos 90 por Guido Van Rossum. O python possu´ı um modelo de desenvolvimento comunit´ario, aberto e geren- ciado pela organizac¸˜ao Pyhon Software Foundation(https://www.python.org/). Atrav´es do link informado anteriormente, tamb´em ´e poss´ıvel encontrar no site o download da linguagem, bem como, as diferentes implementac¸˜oes, a documentac¸˜ao, dentre outros recursos. A linguagem foi projetada de forma a priorizar e enfatizar a importˆancia do esforc¸o do programador sobre o esforc¸o computacional, ou seja, a linguagem prioriza a legibilidade do c´odigo sobre a velocidade. Possu´ı uma combinac¸˜ao entre a sintaxe con- cisa e clara com os recursos poderosos da biblioteca padr˜ao, bem como, os m´odulos e frameworks desenvolvidos pela comunidade. Al´em disso, ´e uma linguagem de alto n´ıvel, multi-paradigma, ou seja, suporta paradigma orientado a objetos, imperativo funcional e procedural. Por fim, ´e uma linguagem bastante utilizada no processamento de textos, dados cient´ıficos, dentre outras ´areas. [Tulchak and Marchuk ] Utilizamos a linguagem Python no projeto, pois a mesma oferece um recurso de integrac¸˜ao com a linguagem C, al´em disso, torna poss´ıvel atrav´es do framework Flask, o desenvolvimento da aplicac¸˜ao web. 3.5. CUDA Anteriormente, a API CUDA era conhecida por Compute Unified Device Architecture e ´e destinada a computac¸˜ao paralela, GPGPU e computac¸˜ao heterogˆenea criada pela empresa Nvidia, destinada a placas gr´afica com chipset da Nvidia. A plataforma fornece acesso ao conjunto de instruc¸˜oes virtuais da GPU e tamb´em a elementos da computac¸˜ao paralela para a execuc¸˜ao de n´ucleos de computac¸˜ao. A API possu´ı um conjunto de instruc¸˜oes CUDA ISA’s, al´em do mecanismo de computac¸˜ao paralela na GPU. Ele exp˜oe os tipos de mem´oria da placa de v´ıdeo e torna obrigat´orio por parte do desenvolvedor que configure os acessos da mem´oria global,
  • 6. cache, bem como, a disposic¸˜ao e quantidade dos threads. Por fim, tamb´em ´e de respons- abilidade do desenvolvedor escalonar as atividades entre a GPU e CPU. A proposta inicial da Nvidia era que a API fosse destinada a propriedades f´ısicas em jogos, analisar fluxo do tr´afego, visualizac¸˜ao de mol´eculas e identificar placas ocul- tas em art´erias. Entretanto, muitos desenvolvedores ao redor do mundo observaram no CUDA uma tentativa e oportunidade de aprimorar suas aplicac¸˜oes. Dessa forma, out- ras ´areas comec¸aram a fazer uso da API, como por exemplo: inteligˆencia artificial (o framework da Google TensorFlow, faz uso do CUDA) e redes blockchain. Nos dias de hoje, a plataforma CUDA, ´e das plataformas, de GPGPU mais robustas que existem, jus- tificando assim o prec¸o mais alto de suas placas gr´aficas comparadas com as de suas concorrentes. Por fim, nas vers˜oes antigas do CUDA Toolkit, era poss´ıvel fazer uso da ferramenta mesmo sem possuir uma placa gr´afica, atrav´es de um emulador, era poss´ıvel desenvolver. No entanto, a partir da vers˜ao 3.0, a Nvidia removeu essa funcionalidade. [Nvidia ] Utilizamos a API CUDA no projeto, pois a mesma oferece um poder computa- cional que em combinac¸˜ao com a programac¸˜ao paralela, aumentar´a o desempenho da nossa aplicac¸˜ao. 3.6. Flask O Flask ´e um framework web desenvolvido e escrito na linguagem de programac¸˜ao Python, baseado nas bibliotecas WSGI Werkzeug e Jinja2. Al´em disso, o Flask ´e disponi- bilizado sob os termos da licenc¸a BSD. Na p´agina do mesmo, ´e poss´ıvel encontrar uma breve descric¸˜ao sobre a ferramenta, onde atrav´es da pr´opria p´agina, ele ´e chamado de micro framework, pois mantem um n´ucleo bastante simplificado, no entanto, estend´ıvel. Isso ocorre, pois n˜ao h´a uma camada de abstrac¸˜ao do banco de dados, validac¸˜ao de for- mul´arios, ou outros componentes semelhantes. Dessa forma, o Flask suporta diversas extens˜oes que s˜ao capazes de adicionar e prover tais funcionalidades. [Flask ] A escolha do micro framework foi bastante clara e objetiva, uma vez que, para que a parte web da nossa aplicac¸˜ao funcionasse como n´os gostar´ıamos, n˜ao era necess´ario um framework completo com diversos recursos embutidos que acabar´ıamos n˜ao utilizando. Dessa forma, o Flask nos permitiu adicionar somente as extens˜oes e funcionalidades que de fato utilizamos em nossa aplicac¸˜ao. 3.7. Processamento Paralelo O processamento paralelo (parallel processing) ´e uma forma eficiente do processamento da informac¸˜ao com ˆenfase na explorac¸˜ao de eventos simultˆaneos na execuc¸˜ao de um soft- ware. A motivac¸˜ao para o processamento paralelo ´e a possibilidade de aumentar a capaci- dade de processamento de uma ´unica m´aquina. Com a limitac¸˜ao tecnol´ogica da veloci- dade das m´aquinas sequenciais, a soluc¸˜ao empregada para aumentar o poder de proces- samento ´e a utilizac¸˜ao de processadores em paralelo. Assim, com o paralelismo torna-se poss´ıvel ultrapassar as limitac¸˜oes impostas pela utilizac¸˜ao de um ´unico processador, tais como frequˆencia de operac¸˜ao, dissipac¸˜ao de potˆencia e outras. A utilizac¸˜ao do paralelismo nos projetos de arquitetura de computadores tem pos- sibilitado um aumento significativo na velocidade de processamento devido `a execuc¸˜ao simultˆanea de diversas tarefas. Contudo, os aspectos relacionados ao software paralelo
  • 7. e `a paralelizac¸˜ao dos programas s˜ao essenciais para o desempenho do sistema paralelo. [Ferlin 2011] Al´em disso, um thread tamb´em pode ser entendido como um processo que pode pertencer a uma aplicac¸˜ao ou a aplicac¸˜oes completamente distintas e independentes. Sistemas com um ´unico processador podem gerenciar v´arios threads simultaneamente atrav´es de m´etodos de Time Slice, fornecendo para cada processo uma fatia de tempo da CPU (n˜ao necessariamente o mesmo tempo para todos os processos). Dito isso, cada processo pode conter um n´ıvel de prioridade: os threads com alta prioridade podem in- terromper threads de menor prioridade. No entanto, por melhor que seja o gerenciamento dos threads por parte da aplicac¸˜ao ou do sistema operacional, o Time Slice sempre pode trazer certa lentid˜ao/latˆencia, devido o compartilhamento de cache ou a dificuldade de gerenciamento entre o trˆansito de processos. [Tanenbaum 2015] A escolha de se usar o recurso computacional do processamento paralelo se deu, uma vez que, quer´ıamos acelerar os procedimentos de validac¸˜ao de CPF, Regi˜ao e Con- tagem dos votos. 3.8. Trabalhos Correlatos O n´umero de pesquisas, trabalhos e artigos voltados para o desenvolvimento ou estudo do sistema eleitoral ´e quase que inexistente, a maior parte das buscas realizadas retornam resultados ligados diretamente ao governo, de forma que, os c´odigos s´o est˜ao dispon´ıveis aos candidatos ao governo e especialistas da ´area. Dessa forma, a escolha pelo trabalho correlato levou em conta as ferramentas e tecnologias que usamos no desenvolvimento do presente artigo, n˜ao necessariamente abrangendo algoritmos semelhantes ao usado por n´os, uma vez que, n˜ao foi poss´ıvel encontrar trabalhos e pesquisas s´olidas na ´area de servidores ligados ao sistema eleitoral como um todo. TensorFlow: O TensorFlow ´e uma biblioteca de c´odigo aberto com o prop´osito voltado para o aprendizado de m´aquina aplic´avel a uma ampla variedade de tarefas. Dito isso, ´e um sistema para treinamento e criac¸˜ao de redes neurais capazes de detectar e decifrar padr˜oes e correlac¸˜oes, `a forma como humanos aprendem e raciocinam. O TensorFlow foi desen- volvido pela equipe Google Brain para uso interno na empresa e aos poucos est´a substi- tuindo o seu antecessor DistBelief. A biblioteca foi lanc¸ada em 2015 sob a licenc¸a de c´odigo aberto Apache 2.0. O TensorFlow est´a dispon´ıvel nas vers˜oes de 64 bits Windows, MacOs, Linux e computac¸˜ao m´ovel, incluindo Android e iOS. Dessa forma, apesar da implementac¸˜ao de referˆencia sugira que a mesma seja executada em dispositivos individuais, a biblioteca tamb´em pode ser executada em m´ultiplas CPU’s e GPU’s (com extens˜oes opcionais CUDA para GPGPU). [TensorFlow ] 4. Proposta e Desenvolvimento 4.1. Proposta Temos como objetivo/proposta o desenvolvimento de uma aplicac¸˜ao, atrav´es do uso da programac¸˜ao paralela juntamente da API CUDA, que ser´a respons´avel por receber ar- quivos no formato .txt com um cabec¸alho pr´e-definido e, ap´os o recebimento do arquivo,
  • 8. iniciar a validac¸˜ao do CPF por eleitor, bem como, o n´umero do candidato escolhido. Por fim, ser´a feita a contagem total dos votos que indicar´a o candidato que ser´a eleito. 4.2. Desenvolvimento Para que o desenvolvimento do presente artigo pudesse ser realizado, foi preciso fazer uso de tecnologias distintas (citadas na sec¸˜ao 2). Dessa forma, o desenvolvimento da aplicac¸˜ao foi separado por etapas. S˜ao elas: • Etapa 1 - Prot´otipo em HTML e CSS da tela web. • Etapa 2 - Implementac¸˜ao da parte web. • Etapa 3 - Algoritmo de validac¸˜ao do arquivo. • Etapa 4 - Algoritmo de validac¸˜ao de CPF. • Etapa 5 - Algoritmo de validac¸˜ao da Regi˜ao. • Etapa 6 - Algoritmo de contagem dos votos. • Etapa 7 - Fila de processamento. Para cada etapa listada acima, ser´a definido o modelo de implementac¸˜ao, carac- ter´ıstica de cada etapa e sua importˆancia no projeto, complexidade do algoritmo, dentre outras definic¸˜oes. 4.3. Prot´otipo em HTML e CSS da tela web No modelo eleitoral existente no Brasil hoje, ap´os o t´ermino do hor´ario da eleic¸˜ao, ´e re- movido de cada urna uma mem´oria contendo todos os votos realizados. Ap´os a remoc¸˜ao, os respons´aveis pelas urnas se encaminham at´e uma sala espec´ıfica em cada local de votac¸˜ao e, atrav´es de uma intranet enviam os dados da mem´oria para o servidor. Para que pud´essemos simular esse mecanismo de envio de dados, optamos por criar uma p´agina web. Atrav´es dessa p´agina, os demais grupos do PI, conseguem enviar 2 arquivos diferentes e selecionar o estado da federac¸˜ao. O primeiro arquivo que deve ser selecionado na p´agina ´e referente aos candidatos que concorrem a vagas estaduais. O segundo arquivo refere-se aos dados dos candidatos com os votos (Figure 1). Por fim, para que seja poss´ıvel enviar os dados referentes `a urna, ´e preciso clicar no ´ıcone. O tratamento, bem como, a organizac¸˜ao desses arquivos ser´a explicado posteriormente. O visual da p´agina foi constru´ıdo atrav´es do uso do HTML5 e o framework Boot- strap. Al´em disso, foi criado um pequeno ”mecanismo” visual de carregamento. Esse ”mecanismo” ´e ativado no momento em que o usu´ario clicar no ´ıcone da urna e, enquanto ´e feito o upload do arquivo o sistema apresentar´a esse carregamento.(Figure 2) 4.4. Desenvolvimento da tela web Ap´os o design de a tela ter sido definido, foi preciso tornar a tela dinˆamica, de forma que, ao clicar no ´ıcone para enviar os dados, a nossa aplicac¸˜ao pudesse receber os arquivos de forma correta. Dito isso, usamos o micro framework Flask para que pudesse tornar tal ac¸˜ao vi´avel. A organizac¸˜ao e estrutura das pastas ligadas a p´agina web pode ser vista atrav´es da (Figure 6). Atrav´es do uso de boas pr´aticas para programac¸˜ao de p´aginas web, deixamos acess´ıvel ao usu´ario da tela, apenas o necess´ario e essencial, ou seja, todas as estruturas de validac¸˜ao de formul´ario e a lista dos estados da federac¸˜ao (poss´ıvel ser visto atrav´es do SELECT no formul´ario) est˜ao todos encapsulados no back-end.
  • 9. 4.5. Algoritmo de validac¸˜ao do arquivo Para que n˜ao houvesse nenhum tipo de conflito entre os grupos na hora de gerar o arquivo com os votos, criou-se um cabec¸alho padr˜ao para o arquivo com os dados dos candidatos e o arquivo com os dados dos eleitores. O formato escolhido inicia-se com o n´umero 1 seguido do separador ’;’ na sequˆencia, ´e apresentado o t´ıtulo de cada coluna. O n´umero 1 representa o cabec¸alho e o n´umero 2 representa os dados (Figure 7) e (Figure 8). No momento em que o usu´ario submete os arquivos, o sistema ir´a validar o ar- quivo como um todo. Nesse momento, a primeira validac¸˜ao que ocorre, ´e com relac¸˜ao a extens˜ao do arquivo. Caso o arquivo esteja em um formato diferente da extens˜ao .txt, a aplicac¸˜ao ir´a retornar o status 401 e, consequentemente, ser´a apresentado na tela uma mensagem de erro. Caso n˜ao apresente nenhum problema com relac¸˜ao `a extens˜ao do arquivo, ser´a feito ent˜ao, a leitura dos arquivos para identificar se ambos est˜ao no formato correto. Nesse momento, ´e criado duas threads, um thread ser´a destinado `a validac¸˜ao do arquivo do candidato e a outra respons´avel pelo arquivo do eleitor. O algoritmo para verificar se a estrutura est´a de acordo com o informado ´e a mesma para ambos os arquivos. O algoritmo criado faz a leitura apenas da primeira linha e, atrav´es do identificador ’;’ ´e separado cada parte do cabec¸alho. Com a separac¸˜ao dos t´ıtulos ´e feita uma verificac¸˜ao um por um para identificar se o t´ıtulo est´a correto ou n˜ao. Ao final, caso a estrutura de ambos os arquivos estejam corretas, o arquivo ´e salvo de acordo com o nome do grupo informado e, ent˜ao, seguir´a para a pr´oxima validac¸˜ao que ´e a do CPF de cada eleitor. Caso tenha algum problema ao longo da verificac¸˜ao, ´e retornado o status 406 e apresentado uma mensagem de erro na tela (Figure 4) e (Figure 5). A validac¸˜ao do cabec¸alho ´e muito importante, uma vez que, caso o cabec¸alho venha com os t´ıtulos na ordem trocada, ou at´e mesmo, com os nomes incorretos, a prob- abilidade de que as linhas referentes aos votos ou os dados referentes aos candidatos tamb´em estejam incorretos ´e bastante alta. Dessa forma, esse procedimento inicial de validac¸˜ao tenta evitar problemas futuros na hora da validac¸˜ao do CPF e n´umero do can- didato, bem como, na contabilizac¸˜ao dos votos. A complexidade do algoritmo demonstrado acima ´e: O(N). 4.6. Algoritmo de validac¸˜ao de CPF A validac¸˜ao do CPF de cada eleitor ´e feita ap´os a verificac¸˜ao dos arquivos enviados pelos estados da federac¸˜ao. Nesse momento, foram desenvolvidos dois algoritmos na tentativa de identificar o mais perform´atico, dessa forma, o primeiro foi feito usando a linguagem de programac¸˜ao Python atrav´es de um simples FOR percorrendo linha por linha do ar- quivo e passando os dados de cada linha para a func¸˜ao/m´etodo de verificac¸˜ao de CPF (C´odigo 3). A complexidade do algoritmo demonstrado acima ´e: O(N). O segundo algoritmo desenvolvido, foi usando a API da Nvidia, o CUDA. A partir desse momento, a complexidade no desenvolvimento da aplicac¸˜ao cresceu exponencial- mente, ou seja, foi preciso entender muito bem o funcionamento dos blocos na placa de v´ıdeo, bem como, a transferˆencia das informac¸˜oes do HOST para o DEVICE. Semelhante ao algoritmo anterior ´e lido o dado de cada linha do arquivo atrav´es de um WHILE, nesse
  • 10. momento, ´e feita as devidas alocac¸˜oes de cada linha em um vetor ´unico. Ap´os a alocac¸˜ao de cada linha do arquivo enviado, ´e feita a preparac¸˜ao para o CUDA, ou seja, criamos os ponteiros, bem como, suas alocac¸˜oes. Al´em disso, ´e feita a transferˆencia dos dados do HOST para o DEVICE atrav´es da func¸˜ao cudaMemcpy (C´odigo 1). Ap´os a transferˆencia dos dados para a placa de v´ıdeo, ´e definido o n´umero de blo- cos que ser˜ao usados (C´odigo 2). Com o n´umero de blocos e a quantidade de threads definidas, ´e feita ent˜ao a chamada da func¸˜ao valida (faz uso do paralelismo). Nessa func¸˜ao, ´e feita a identificac¸˜ao do vetor dentro do bloco e, ap´os a identificac¸˜ao, para cada linha ´e chamada a func¸˜ao respons´avel pela validac¸˜ao do CPF (C´odigo 3). Com a validac¸˜ao finalizada, ´e feito a c´opia dos dados do DEVICE para o HOST. Por fim, caso a aplicac¸˜ao identifique algum CPF inv´alido, ´e adicionado em um vetor de tamanho fixo de 10 posic¸˜oes, o n´umero da linha que cont´em o problema. No entanto, mesmo tendo lim- itado o tamanho do vetor em 10 posic¸˜oes, n˜ao ´e poss´ıvel parar a execuc¸˜ao da validac¸˜ao, pois como o arquivo ´e separado em diversos blocos, n˜ao ´e poss´ıvel saber quais ainda est˜ao em execuc¸˜ao. Dito isso, ´e retornado para a tela as linhas referentes aos votos que pos- suem problema com relac¸˜ao ao CPF (Figure 4). Caso n˜ao tenha problemas na validac¸˜ao, ´e encerrado esse procedimento e seguir´a para a pr´oxima validac¸˜ao. A validac¸˜ao do CPF ´e de suma importˆancia para a aplicac¸˜ao, uma vez que, para que um voto seja contabilizado de forma correta e v´alida, ´e preciso que o eleitor tenha um CPF v´alido. Um detalhe importante a ser descrito, ´e que como as urnas eleitorais possuem a funcionalidade de multiplicac¸˜ao dos votos, ou seja, ir´a ocorrer repetic¸˜ao dos CPF’s para os diferentes votos, o servidor n˜ao faz uma validac¸˜ao de singularidade de voto. Problemas encontrados pelo uso da abordagem acima: • Uso de vari´aveis auxiliares: – ´E muito comum ao longo da aplicac¸˜ao encontrar vari´aveis que sejam aux- iliares. Dito isso, uma dessas vari´aveis ´e a ”idx”, ela ´e utilizada para guardar os ´ındices. O problema no uso de uma vari´avel auxiliar utilizando simultaneamente o processamento paralelo juntamente da API CUDA, ´e que o processamento das linhas est´a ocorrendo de forma simultˆanea, ou seja, pode ser que duas linhas apresentem erro simultaneamente e tentem fazer uso do mesmo ´ındice, nesse momento, como est˜ao tentando acessar a mesma vari´avel um erro ir´a sobrescrever o outro. – Soluc¸˜ao: Como a programac¸˜ao em CUDA ´e feita atrav´es do uso da lin- guagem C, encontramos uma palavra chave na linguagem chamada de ”register”. Os registers s˜ao mais r´apidos que as mem´orias de acesso, dessa forma, como o pr´oprio nome sugere, s˜ao vari´aveis que ser˜ao ar- mazenadas nos registradores e n˜ao nas mem´orias principais. Isso solu- ciona uma parte do problema, pois agora o acesso `a mem´oria ´e feito de forma muito mais r´apida. Al´em disso, usamos uma func¸˜ao da API CUDA chamada de ”atomicAdd”, como as linhas s˜ao armazenadas em blocos den- tro da placa de v´ıdeo, toda vez que uma linha ´e processada ´e usada a func¸˜ao ”atomicAdd” que ir´a realizar uma adic¸˜ao atˆomica a uma vari´avel (c´odigo 4). • Vetor com o n´umero das linhas que contenham problemas no CPF: – Como a aplicac¸˜ao foi criada para que fizesse uso do recurso de threads, ´e poss´ıvel que durante a validac¸˜ao, dois CPF’s estejam inv´alidos simultane-
  • 11. amente provocando na n˜ao ordenac¸˜ao das linhas, al´em disso, n˜ao ´e garan- tido que ao enviar o mesmo arquivo com problemas de linhas inv´alidas, a aplicac¸˜ao retorne as mesmas linhas. Isso ocorre novamente pelo uso dos threads, pode ser que uma linha seja processada antes da outra e, nesse momento, a linha a ser inserida no vetor seja diferente. A complexidade do segundo algoritmo demonstrado acima ´e: O(N/1024). 1 CUDA_SAFE_CALL(cudaMalloc(&d_lines, next*sizeof(char))); 2 CUDA_SAFE_CALL(cudaMalloc(&d_ind, MAXLINES*sizeof(unsigned)) ); 3 CUDA_SAFE_CALL(cudaMalloc(&d_lerror, 10*sizeof(int))); 4 5 CUDA_SAFE_CALL(cudaMemcpy(d_lerror, h_lerror, 10*sizeof(int) , cudaMemcpyHostToDevice)); 6 CUDA_SAFE_CALL(cudaMemcpy(d_lines, h_lines, next*sizeof(char ), cudaMemcpyHostToDevice)); 7 CUDA_SAFE_CALL(cudaMemcpy(d_ind, ind, MAXLINES*sizeof( unsigned), cudaMemcpyHostToDevice)); C´odigo 1 - Transferˆencia e alocac¸˜ao de mem´oria no CUDA. 1 // cont -> Quantidade de linhas do arquivo 2 // n_threads -> Valor fixo de 1024 3 int n_blocos = (cont + n_threads - 1) / n_threads; C´odigo 2 - Definic¸˜ao da quantidade de blocos. 1 __device__ int validarCPF(char cpf[]) { 2 int i, j, digito1 = 0, digito2 = 0; 3 if(lenght(cpf) != 11) 4 return 1; 5 else if((compare(cpf,"00000000000", 11) == 0) || (compare( cpf,"11111111111", 11) == 0) || (compare(cpf,"22222222222 ", 11) == 0) || 6 (compare(cpf,"33333333333", 11) == 0) || (compare( cpf,"44444444444", 11) == 0) || (compare(cpf," 55555555555", 11) == 0) || 7 (compare(cpf,"66666666666", 11) == 0) || (compare( cpf,"77777777777", 11) == 0) || (compare(cpf," 88888888888", 11) == 0) || 8 (compare(cpf,"99999999999", 11) == 0)) 9 return 1; //se o CPF tiver todos os numeros iguais ele invalido. 10 else { 11 //digito 1--------------------------------------------------- 12 for(i = 0, j = 10; i < lenght(cpf)-2; i++, j--) // multiplica os numeros de 10 a 2 e soma os resultados dentro de digito1 13 digito1 += (cpf[i]-48) * j;
  • 12. 14 digito1 %= 11; 15 if(digito1 < 2) 16 digito1 = 0; 17 else 18 digito1 = 11 - digito1; 19 if((cpf[9]-48) != digito1) 20 return 1; //se o digito 1 no for o mesmo que o da validao CPF invlido 21 else { 22 //digito 2-------------------------------------------------- 23 for(i = 0, j = 11; i < lenght(cpf)-1; i++, j--) // multiplica os numeros de 11 a 2 e soma os resultados dentro de digito2 24 digito2 += (cpf[i]-48) * j; 25 digito2 %= 11; 26 if(digito2 < 2) 27 digito2 = 0; 28 else 29 digito2 = 11 - digito2; 30 if((cpf[10]-48) != digito2) 31 return 1; //se o digito 2 no for o mesmo que o da validacao CPF invalido 32 } 33 } 34 return 0; 35 } C´odigo 3 - Func¸˜ao/M´etodo - Validar CPF. 1 register int idx = atomicAdd(total, r); C´odigo 4 - Exemplificac¸˜ao do uso da palavra chave register e uso da func¸˜ao atomicAdd. 4.7. Algoritmo de validac¸˜ao da Regi˜ao Para a validac¸˜ao da Regi˜ao pensamos em dois algoritmos diferentes que iriam atender o nosso prop´osito, no entanto, umas das abordagens que tentamos n˜ao funcionou corretamente e ser´a descrito mais a frente o porque de n˜ao ter dado certo. A abordagem que desenvolvemos ´e semelhante a validac¸˜ao do cabec¸alho. Inicialmente criamos uma lista no Python contendo o grupo de estados referentes a cada grupo, segue a lista: Grupo A: [’PR’,’SC’,’RS’]; Grupo B: [’RN’,’CE’,’PI’]; Grupo C: [’ES’,’BA’,’SE’]; Grupo D: [’AL’,’PE’,’PB’]; Grupo E: [’SP’,’MG’,’RJ’]; Grupo F: [’MA’,’AP’,’PA’]; Grupo G: [’AM’,’AC’,’RR’]; Grupo H: [’DF’,’GO’,’MS’];
  • 13. Grupo I: [’MT’,’TO’,’RO’]. Ap´os a lista ter sido definida, criamos uma func¸˜ao (c´odigo 5) que ir´a retornar para um vetor o valor em decimal do estado. Esse valor pode ser consultado atrav´es da tabela ASCII. Com os valores dentro do vetor, ´e feita a alocac¸˜ao do vetor na mem´oria da placa de v´ıdeo, assim como na validac¸˜ao do CPF. Ap´os a alocac¸˜ao, ´e enviado para o m´etodo ”valida” todas as informac¸˜oes necess´arias para a validac¸˜ao. Dentro da func¸˜ao ”valida”, criamos um lac¸o de repetic¸˜ao respons´avel por com- parar o valor em decimal apresentado pela linha com a lista que criamos anteriormente. Caso esteja sem nenhum problema na linha vai para o pr´oximo ´ındice, caso algum ´ındice apresente problema, para que exista uma separac¸˜ao entre problema com o CPF e problema com o estado, adicionamos o valor da linha com problema com o seu valor negativo. Com relac¸˜ao a primeira abordagem que ir´ıamos seguir, tentamos criar um vetor e conforme ´ıamos percorrendo as linhas, verificav´amos se o estado j´a havia sido preenchido ou n˜ao, caso n˜ao estivesse no vetor inser´ıamos ele, caso j´a estivesse, prosseguimos com a validac¸˜ao. O problema dessa abordagem j´a foi mencionada anteirormente, como a aplicac¸˜ao est´a fazendo uso do processamento paralelo, duas linhas distintas tentavam acessar simultaneamente o mesmo ´ındice do vetor, no entanto, para essa abordagem n˜ao conseguimos solucionar o problema fazendo uso dos ”registers” ou atomicAdd. Al´em disso, o desenvolvimento do primeiro algoritmo citado, funcionou muito bem com a nossa aplicac¸˜ao, dessa forma, optamos por n˜ao prosseguir com essa metodologia. A complexidade do segundo algoritmo demonstrado acima ´e: O(N/1024). 1 for(int i=0; i<6; i++) 2 h_state[i] = (int)PyFloat_AsDouble(PyList_GetItem( state_list, i)); C´odigo 5 - Convers˜ao da lista em Pyhon para valor em decimal referente ao estado. 4.8. Algoritmo de contagem dos votos O procedimento inicial para o desenvolvimento do algoritmo respons´avel pela contagem dos votos ´e um pouco parecido com o algoritmo de validac¸˜ao do CPF. Para que fosse poss´ıvel a implementac¸˜ao, utilizamos o processamento paralelo juntamente do processa- mento dos dados na placa de v´ıdeo (API CUDA). Ap´os todas as validac¸˜oes terem sido efetuadas com sucesso, a contagem dos vo- tos dos candidatos federais entra em ac¸˜ao. ´E feita a leitura do arquivo chamado presi- dentes.txt, que possu´ı a estrutura referente a imagem (Figure 7), essa leitura ´e feita atrav´es da linguagem de programac¸˜ao Python e, ent˜ao, ´e criada uma lista contendo o nome do candidato juntamente do seu c´odigo, ap´os a lista ter sido definida, ´e enviado por meio da API de integrac¸˜ao entre Python e o C essa lista (c´odigo 6). Ap´os a convers˜ao, ´e feita a alocac¸˜ao da vari´avel e c´opia da variv´avel auxiliar na mem´oria da placa de v´ıdeo (c´odigo 7). Com todo o estado da placa de v´ıdeo pronto e preparado para iniciar o processa- mento, ´e acionada a func¸˜ao ”valida”. Na func¸˜ao valida ´e feito inicialmente a validac¸˜ao da Regi˜ao e posteriormente do CPF e logo em seguida entra a func¸˜ao respons´avel por fazer a
  • 14. comprac¸˜ao da lista dos candidatos enviada para a placa de v´ıdeo e o dado que est´a na linha do arquivo. Como o tamanho do campo ”c´odigo do candidato” ´e fixado em 2 posic¸˜oes, ´e criada uma vari´avel que ir´a armazenar em posic¸˜oes distintas do vetor cada valor do dado. Com os valores definidos, ´e feita a convers˜ao dos caracteres e, ent˜ao, estar´a pronto para passar por um lac¸o de repetic¸˜ao varrendo a lista dos candidatos poss´ıveis e incrementando o vetor de resultados de cada candidato, uma vez que, ´e feita a paridade entre os c´odigos. Problemas encontrados pelo uso da abordagem acima: • Convers˜ao do c´odigo do candidato do arquivo para inteiro: – Quando chegamos no momento de realizar a comparac¸˜ao entre os c´odigos dos candidatos que foram enviados para a placa de v´ıdeo e o valor do candidato presente no arquivo n˜ao sabiamos como iria ser feita essa comparac¸˜ao, pois o dado que ´e extra´ıdo do arquivo vem em formato de um vetor de strings, nesse momento, pensamos em realizar a convers˜ao do valor do caracter para bin´ario, no entanto, essa abordagem n˜ao funcionaria, uma vez que, o valor em bin´ario do caracter ’9’ ´e diferente do valor em bin´ario do n´umero 9. Como essa m´etodo descrito n˜ao funcionaria, pen- samos em criar no Python a lista com os valores em string ao inv´es de valor inteiro, no entanto, quando fossˆemos retornar o vetor de resultados com os valores em string teriamos problemas em realizar a contabilizac¸˜ao total. Por fim, encontramos a soluc¸˜ao que ´e descrita no (c´odigo 8) que funciona perfeitamente para a nossa proposta. A complexidade do segundo algoritmo demonstrado acima ´e: O(N/1024). 1 // Candidato 2 int size_tt = PyList_Size(state_list); 3 4 int h_cd[size_tt-6]; 5 int h_aux_cd[size_tt-6]; 6 int resultado[size_tt-6]; 7 int idx_cd = 0; 8 9 for(int i=0; i<size_tt; i++){ 10 if(i < 6) 11 h_state[i] = (int)PyFloat_AsDouble(PyList_GetItem( state_list, i)); 12 else{ 13 // Candidatos 14 h_cd[idx_cd] = (int)PyFloat_AsDouble(PyList_GetItem( state_list, i)); 15 h_aux_cd[idx_cd] = 0; 16 resultado[idx_cd++] = 0; 17 } 18 } C´odigo 6 - Convers˜ao da lista em Python. 1 CUDA_SAFE_CALL(cudaMalloc(&d_aux_cd, (size_tt-6)*sizeof(int) ));
  • 15. 2 CUDA_SAFE_CALL(cudaMemcpy(d_aux_cd, h_aux_cd, (size_tt-6)* sizeof(int), cudaMemcpyHostToDevice)); C´odigo 7 - Alocac¸˜ao e c´opia da vari´avel para a placa de v´ıdeo. 1 char cd_federal[2]; 2 3 cd_federal[0] = string[cont]; 4 cont++; 5 cd_federal[1] = string[cont]; 6 7 int cod = (cd_federal[0] - ’0’)*10 + (cd_federal[1] - ’0’); C´odigo 8 - Convers˜ao dos valores da linha. 4.9. Fila de processamento Ap´os todos os passos descritos acima, optamos por implementar um mecanismo de fila de processamento. Desenvolvemos a fila com o intuito de evitar que dois grupos envi- assem o arquivo para o servidor de forma simultˆanea e ocasionasse em algum problema no processamento. Dito isso, a fila funciona da seguinte forma: no momento em que a aplicac¸˜ao ´e iniciada o job respons´avel por ficar verificando se existe algum arquivo para validar ou n˜ao ´e acionado. Quando um grupo submete um arquivo para a validac¸˜ao e contagem dos votos, esse arquivo ´e armazenado em um diret´orio chamado de ”n˜ao val- idado”, o job fica verificando esse diret´orio a procura de arquivos para serem validados, caso encontre algum arquivo no diret´orio, o job ir´a enviar o arquivo para os fluxos de validac¸˜ao e contagem. Caso um grupo tente reenviar um arquivo que ainda est´a na fila para ser processado, retornamos uma mensagem de erro na tela (Figure 11). 5. Experimentos e An´alise dos Resultados Nessa sec¸˜ao apresentamos os resultados obtidos pela aplicac¸˜ao de acordo com cada implementac¸˜ao, bem como, os tipos de experimentos que realizamos com o intuito de chegarmos a uma conclus˜ao plaus´ıvel com relac¸˜ao aos resultados. Os testes foram realizados utilizando a aplicac¸˜ao feita em CUDA (processamento paralelo, integrac¸˜ao de linguagens, utilizac¸˜ao de processamento dentro da placa de v´ıdeo) e tamb´em realizada no Python (utilizac¸˜ao de threads). Os testes n˜ao levam em conta o tempo que a aplicac¸˜ao leva para receber o arquivo (upload), apenas o tempo que leva para executar os processos de validac¸˜ao e contagem. Os testes realizados foram feitos para um total de cem, mil, dez mil, cem mil, um milh˜ao, dez milh˜oes e sessenta milh˜oes de linhas.we Atrav´es da an´alise das imagens (Figure 9) e (Figure 10) ´e poss´ıvel chegar a con- clus˜ao de que a utilizac¸˜ao do CUDA para uma massa de testes de at´e dez mil linhas n˜ao ´e vi´avel, acima desse valor, o CUDA ´e extremamente recomend´avel, pois a perfomance adquirida ´e muito superior quando comparado com o Python. A maior discrepˆancia pode ser vista ao validar e contabilizar os votos de um arquivo de sessenta milh˜oes de lin- has, enquanto o CUDA realizou o processamento em aproximadamente dez segundos, o Python levou em torno de 40 minutos. Observac¸˜ao.: O experimento foi realizado em uma m´aquina com as seguintes configurac¸˜oes:
  • 16. • Processador: I7 7700 3.6 GHz • Placa de V´ıdeo: GTX 1060 6GB 8008MHz • Mem´oria Ram: 2x8gb ram 2400MHz 6. Conclus˜ao e Trabalhos Futuros Diante deste estudo/desenvolvimento de algoritmos com o intuito de comparar os resul- tados da aplicac¸˜ao em cada tecnologia, o uso da API CUDA juntamente do recurso com- putacional de programac¸˜ao paralela mostrou-se mais efetivo e eficaz para valores muito altos. Quando comparados com valores muito pequenos, uma abordagem padr˜ao como por exemplo, o uso de linguagem C ou Python, ´e mais efetivo. Com base nos argumentos apresentados, o projeto integrador proposto vai ao en- contro do que foi apresentado nas motivac¸˜oes iniciais. Sendo assim, conclu´ımos que ´e preciso realizar diversos experimentos at´e que seja comprovada a efic´acia do algoritmo, bem como, o recurso computacional. Atrav´es dos resultados expressos na sec¸˜ao anterior ´e poss´ıvel identificar todas as comparac¸˜oes realizadas e, a partir delas, escolher uma poss´ıvel abordagem de acordo com a sua aplicac¸˜ao. Como sugest˜oes de poss´ıveis trabalhos futuros, pode-se apontar a implementac¸˜ao de novos recursos, tais como: • Implementac¸˜ao de novo algoritmo respons´avel pela validac¸˜ao dos candidato; • Uso de inteligˆencia artif´ıcial com o objetivo de extrair e identificar as informac¸˜oes extras enviadas pelos grupos; • Implementac¸˜ao de novo algoritmo respons´avel pela contabilizac¸˜ao dos votos dos candidatos estaduais; • Implementac¸˜ao de novo algoritmo respons´avel pela an´alise do resultado dos votos, ou seja, separac¸˜ao de votos por estados, classe econˆomica. 7. Referˆencia Segue abaixo as referˆencias usadas ao longo da montagem do artigo/aplicac¸˜ao. References Ferlin, E. P. (2011). In O que ´e Processamento Paralelo? - http://professorferlin.blogspot.com/2011/08/o-que-e-processamento-paralelo.html. Flask. In Flask Documentation. Flask 1.0 edition. Microsoft. In Visual Studio Code - https://code.visualstudio.com/. Nvidia. In CUDA Toolkit Documentation. 10.0.130 edition. Schildt, H. (1996). In C - Completo e Total, pages 15–20. Makron Books, 3th edition. Tanenbaum, A. S. (2015). In Sistemas Operacionais Modernos, pages 50–87. S˜ao Paulo, 3th edition. TensorFlow. In Tensor Flow - https://www.tensorflow.org. TSE. In Tribunal Superior Eleitoral - http://www.tse.jus.br/. Tulchak, L. V. and Marchuk, O. A. O. In History of Python, pages 1–3. 1th edition. 8. Imagens
  • 17. Figure 1. Prot´otipo da tela Figure 2. Carregamento da tela
  • 18. Figure 3. Arquivo Enviado com Sucesso Figure 4. Arquivo Inv´alido - problema com CPF
  • 19. Figure 5. Arquivo Inv´alido - problema com estado Figure 6. Estrutura das pastas - Interface Web Figure 7. Modelo do cabec¸alho - Candidatos Figure 8. Modelo do cabec¸alho - Eleitores
  • 20. Figure 9. Tempo de processamento em segundos Figure 10. Preenchimento de ´areas em segundos
  • 21. Figure 11. Erro reportado ao tentar inserir um novo arquivo para processar que j´a est´a na fila