• Nenhum resultado encontrado

5 Implementações e Experimentos do modelo computacional NeuroPON NeuroPON

5.4 RNA MLP com Framework PON C++ 3.0: treinamento BP para IRIS Dataset

Conforme descrito na Seção 3.3.3, o Framework PON C++ 3.0 é uma extensão do Framework PON C++ 2.0 por meio de threads, que visa fornecer uma maneira de distribuir as entidades do PON em múltiplos núcleos de processamento, de forma transparente ao desenvolvedor.

5.4.1 Desenvolvimento e codificação

A implementação da RNA MLP com treinamento BP aqui apresentada segue o mesmo padrão de implementação do experimento demonstrado na Seção 5.3. A

modificação que deve ser feita, no código das estruturas-padrão do Framework, é a identificação do núcleo (core) de execução da entidade PON utilizada. O Código 16 apresenta o código que implementa a Rule rleCalcHidden e seus componentes.

Código 16 - Implementação da Rule rleCalcHidden, utilizando Framework PON C++ 3.0

42 43 44 45 46 47 48 49 50 51

// Adjusts the number of epochs (stats the process)

mthCalcHidden = new MethodPointer<NeuronHidden>(this, &NeuronHidden::calcHidden);

RULE(rleCalcHidden, SingletonScheduler::getInstance(), Condition::CONJUNCTION, this->core); PREMISE(preCalcHidden, this->net->attClock, 2, Premise::EQUAL, Premise::STANDARD, false, this->core);

PREMISE(preCalcHiddenF, this->attDone, false, Premise::EQUAL, Premise::STANDARD, false, this->core);

rleCalcHidden->addPremise(preCalcHidden); rleCalcHidden->addPremise(preCalcHiddenF); rleCalcHidden->addMethod(mthCalcHidden);

Fonte: Autoria Própria

Na declaração da Rule rleCalcHidden e das Premises preCalcHidden e

preCalcHiddenF, do código apresentado no Código 16, o último parâmetro da macro

definida é a informação do núcleo de execução. Implicitamente, a execução das ações implementadas pelos Methods instigados em determinada Rule (neste caso

mthCalcHidden), ocorre no núcleo informado na declaração da própria Rule.

Naturalmente, como a implementação de uma RNA envolve mais de um neurônio, o núcleo de execução é definido via um atributo da própria classe que implementa a FBE Neuron no Framework. Assim, vinculado à instanciação de um neurônio, tanto de camada escondida quanto de saída, é repassada a informação (via valoração de parâmetro) de qual núcleo do microprocessador deverá ser utilizado na execução das ações pertinentes à entidade notificada.

Quanto à execução dos elementos, a Figura 41 apresenta um diagrama de objetos da UML como um exemplo de concorrência na execução das entidades PON.

O diagrama de objetos em UML, mostrado na Figura 41, apresenta um exemplo de computação concorrente entre dois neurônios de camada oculta em uma RNA. O processo de notificação é iniciado quando o valor do Attribute net::attClock é modificado. Tal ajuste notifica as Premises hidneu0::preCalc e hidneu1::preCalc. Deste ponto em diante, todo o processo de notificação e execução das entidades PON ocorre simultaneamente. Por fim, quando os valores dos Attributes hidneu0::attDone e

Figura 41 – Diagrama de objetos em UML: fluxo de execução concorrente das entidades PON, na execução de uma RNA MLP, utilizando Framework PON C++ 3.0

Fonte: Autoria Própria

Além da execução concorrente apresentada na Figura 41, é importante observar que as entidades PON que estão em uma thread acessam entidades PON que estão em outra thread (na Figura 41 as threads estão representadas pelas pistas – lanes). Tal mecanismo é considerado crítico nas execuções em máquinas com microprocessadores multicore. Neste contexto, a exclusão mútua ao acesso às entidades PON compartilhadas é garantida pelos métodos das classes Thread e

SleepCondition, pertencentes ao pacote Multicore do Framework PON C++ 3.0

(apresentado na Seção 3.3.3 Página 108).

5.4.2 Resultados do Experimento

Assim como no experimento efetuado com o Framework PON C++ 2.0, os testes aqui foram conduzidos com 1000 épocas de treinamento. Porém, neste experimento, a inicialização dos pesos sinápticos seguiu os mesmos valores do experimento em Framework PON C++ 2.0. Tal processo foi efetuado visando comparar os valores e a taxa de acerto do algoritmo de treinamento. Neste sentido, em cada execução do algoritmo de treinamento os resultados obtidos foram iguais, em termos de valoração de pesos sináptico e taxa de acerto.

Referente aos dados de desempenho do presente experimento, a Figura 42 apresenta um gráfico comparativo entre os experimentos efetuados em software.

Figura 42 – Tempos de execução (em milissegundos) do treinamento de RNA MLP com método BP, utilizando NeuroPON em materializações de software do PON, para a base de dados da flor de Iris.

Fonte: Autoria Própria

No gráfico da Figura 42, a sigla IP C representa o tempo médio de execução do algoritmo em Linguagem C apresentado na Seção 5.1. Ainda, a sigla FANN (Fast

Artificial Neural Network) é uma implementação alternativa, também baseada no

Paradigma Imperativo. Conforme apresentado na Figura 42, o tempo médio de processamento do treinamento em cem execuções (mil épocas cada) foi de 6987 milissegundos para a implementação no Framework PON C++ 3.0 utilizando apenas 1 núcleo, ou seja, aproximadamente 2,34 vezes mais lento que a versão 2.0 monocore do Framework.

Outrossim, a execução em múltiplos núcleos pode ser observada. A Figura 43 apresenta um screenshot (captura de tela) do histórico da CPU enquanto executando o algoritmo de treinamento do presente experimento.

Figura 43 – Captura de tela (screenshot) do histórico da CPU, apresentando o uso dos núcleos na execução do treinamento multicore, por meio do Framework PON C++ 3.0:

(a) 1 núcleo; (b) 2 núcleos; (c) 4 núcleos; (d) 8 núcleos.

Fonte: Autoria Própria

A Figura 43 apresenta o comportamento dos núcleos de processamento durante a execução do treinamento de uma RNA MLP usando o método BP, por meio do Framework PON C++ 3.0. Neste contexto, mesmo que de modo mais lento, o processo é conduzido nos múltiplos núcleos de processamento do microprocessado utilizado. Tal fator demonstra a plausibilidade da utilização de tal Framework para a construção de RNA contendo entidades concorrentes.

Visando uma análise mais elaborada e precisa do uso dos núcleos de processamento para a execução paralela, utilizou-se o comando top no sistema Linux. Este comando apresenta as informações do sistema e a lista de processos (threads) atualmente gerenciados pelo Kernel do Linux. Para extrair apenas os dados de utilização dos quatro núcleos de execução, o comando foi executado com a opção de simplificar os dados apresentados, e com o tempo de aferição ajustado para 0,5 segundo:

top -b -d 0,5 | grep Cpu > top_cpu.txt

O comando grep foi concatenado à linha de execução para que haja, apenas, os dados dos cores (no caso do comando apresentado é a palavra Cpu). Por fim, os dados são armazenados em arquivo texto para posterior ajustes e tabulação. A Figura

44 apresenta os dados de utilização tabulados, juntamente com um gráfico de linhas, a partir da execução do treinamento utilizando quatro cores.

Figura 44 - Gráfico de utilização do uso de núcleos de processamento por meio do comando TOP em Linux

Fonte: Autoria Própria

Nos dados tabulados e gráfico apresentados na Figura 44, é possível observar que há, realmente, a utilização de todos os núcleos de execução (cores) em paralelo. A ocupação do primeiro núcleo (cpu0 us, na linha na cor azul), em algumas execuções, torna-se muito baixo. Isso se dá pela preempção de processos entre a execução do treinamento em PON e o sistema operacional.

Por fim, visando checar possíveis problemas no uso de recursos do sistema pela aplicação PON multicore, utilizou-se o programa Valgrind (SEWARD, 2019). O Valgrind é um sistema para depuração e criação de perfil de programas Linux, que roda sobre uma licença geral pública (GPL - General Public License). Neste contexto, a execução do programa sobre a aplicação PON durou 30 horas. Os resultados basearam-se em uma verificação feita sobre o uso de memória, e são apresentados na Tabela 12.

A interpretação destes resultados, por meio da documentação da aplicação

Valgrind, indica que os erros residem em leituras e escritas inválidas, em 158 diferentes

áreas de memória, acessadas 16.242 vezes. A indicação de vazamentos “possivelmente perdidos” na memória é causada por problemas relacionados a referências a ponteiros onde, neste caso, não existe um ponteiro inicial para determinada área de memória, mas existe um ponteiro interno naquele espaço de

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 cpu0 us 3 12 58 96 96 98 63 67 13 94 10 96 94 94 91 70 17 18 7 44 87 39 87 50 96 94 91 37 36 86 cpu1 us 2 20 71 96 92 98 76 98 88 92 10 92 94 92 92 75 63 73 79 85 89 52 91 58 96 95 93 54 49 84 cpu2 us 3 14 71 96 96 94 68 82 88 98 98 96 98 92 90 72 73 72 83 84 89 56 94 73 10 94 91 46 51 86 cpu3 us 4 12 82 98 96 10 89 98 92 94 98 96 98 94 94 90 78 83 90 94 92 78 94 83 10 97 97 82 78 70 0 20 40 60 80 100 120 % de u tilizaç ão