modelos de software / hardware reutilizáveis para...

46
Departamento de Electrónica e Telecomunicações Licenciatura em Engenharia de Computadores e Telemática Relatório de Projecto Final de Curso 2003 / 2004 Modelos de Software / Hardware Reutilizáveis para Implementação de Algoritmos Recursivos Orientador: Prof. Doutor Valery Sklyarov Autores: Bruno Figueiredo Pimentel nº mec. 21394 Joel Perdiz Arrais nº mec. 21540

Upload: lambao

Post on 04-Dec-2018

212 views

Category:

Documents


0 download

TRANSCRIPT

DDeeppaarrttaammeennttoo ddee EElleeccttrróónniiccaa ee TTeelleeccoommuunniiccaaççõõeess Licenciatura em Engenharia de Computadores e Telemática

RReellaattóórriioo ddee PPrroojjeeccttoo FFiinnaall ddee CCuurrssoo

22000033 // 22000044

MMooddeellooss ddee SSooffttwwaarree // HHaarrddwwaarree RReeuuttiilliizzáávveeiiss ppaarraa

IImmpplleemmeennttaaççããoo ddee AAllggoorriittmmooss RReeccuurrssiivvooss

OOrriieennttaaddoorr::

Prof. Doutor Valery Sklyarov

AAuuttoorreess::

Bruno Figueiredo Pimentel nº mec. 21394

Joel Perdiz Arrais nº mec. 21540

2

Índice

11.. IINNTTRROODDUUÇÇÃÃOO ...................................................................................................................................................................................................... 44

1.1. CONTEXTUALIZAÇÃO ........................................................................................................... 4

1.2. OBJECTIVOS ....................................................................................................................... 5

22.. PPLLAANNOO DDEE TTRRAABBAALLHHOOSS .................................................................................................................................................................. 66

2.1. RESUMO DA PRIMEIRA ABORDAGEM .................................................................................... 7

2.2. RESUMO DA ABORDAGEM ALTERNATIVA.............................................................................. 8

33.. FFEERRRRAAMMEENNTTAASS................................................................................................................................................................................................ 99

3.1. FPGA UTILIZADA ................................................................................................................ 9

3.2. RC200 ............................................................................................................................... 9

3.3. HANDEL-C ........................................................................................................................ 11

3.4. WINPCAP .......................................................................................................................... 12

3.5. FLUXO DE TRABALHO ........................................................................................................ 12

44.. IIMMPPLLEEMMEENNTTAAÇÇÃÃOO DDEE MMOODDEELLOO DDEE SSUUPPOORRTTEE ÀÀ RREECCUURRSSIIVVIIDDAADDEE.................. 1133

55.. TTRRAANNSSMMIISSSSÃÃOO DDEE DDAADDOOSS ...................................................................................................................................................... 1166

66.. TTAARREEFFAA DDEE CCOO--PPRROOCCEESSSSAAMMEENNTTOO:: SSAATT ...................................................................................................... 1188

77.. MMOODDEELLOO BBAASSEEAADDOO EEMM CCOOMMPPRREESSSSÃÃOO EE DDEESSCCOOMMPPRREESSSSÃÃOO ................................ 1199

7.1. ESCOLHA E DESCRIÇÃO DO ALGORITMO DE COMPRESSÃO................................................... 19

7.2. ALGORITMO DE COMPRESSÃO DE HUFFMAN....................................................................... 19

7.3. IMPLEMENTAÇÃO DO COMPRESSOR E DESCOMPRESSOR EM C++........................................ 23 77..33..11.. CCoommpprreessssoorr eemm CC++++ .................................................................................................................................................................................. 2244 77..33..22.. DDeessccoommpprreessssoorr eemm CC++++........................................................................................................................................................................ 2277

7.4. IMPLEMENTAÇÃO DO DESCOMPRESSOR EM HANDEL-C ....................................................... 28

3

7.5. RESULTADOS DAS EXPERIÊNCIAS COM O MODELO DE TRANSFERÊNCIA IMPLMENTADO.......... 31

88.. AABBOORRDDAAGGEEMM AALLTTEERRNNAATTIIVVAA:: FFOORRMMAATTOO CCOOMMPPRRIIMMIIDDOO .................................................... 3344

8.1. FORMATO COMPRIMIDO PARA MATRIZES SAT3: CS3M....................................................... 35

8.2. SAT3-SOLVER-CORE........................................................................................................ 37

8.3. INCORPORAÇÃO DE GESTOR DE COMUNICAÇÃO ................................................................. 41

8.4. RESULTADOS DAS EXPERIÊNCIAS COM O SAT3-SOLVER .................................................... 42

99.. CCOONNCCLLUUSSÕÕEESS ................................................................................................................................................................................................ 4444

1100.. RREEFFEERRÊÊNNCCIIAASS............................................................................................................................................................................................ 4455

10.1. PUBLICAÇÕES BASEADAS NESTE ESTUDO......................................................................... 46

4

1. Introdução

Este relatório descreve o trabalho realizado no projecto final do curso de

Licenciatura em Engenharia de Computadores e Telemática da Universidade de

Aveiro no ano lectivo de 2003/2004.

O título do projecto é “Modelos de Software/Hardware reutilizáveis para

implementação de algoritmos recursivos”. O orientador foi o Professor Valery

Sklyarov.

1.1. Contextualização

Na realização de tarefas de grande complexidade, a utilização de co-

processadores com características mais adequadas tem como objectivo reduzir o

tempo da sua realização. Assim, para tirar partido da eficiência que o hardware

permite, os computadores de uso geral podem ser ligados a plataformas de

características reconfiguráveis, como as que se baseiam em FPGA's.

Perante tarefas que implicam grandes quantidades de dados, a largura de

banda do canal de transferência pode ser um factor limitativo da taxa de

realização das tarefas. A resolução deste problema pode passar por uma

compressão dos dados, podendo esta ser genérica ou específica para um

determinado tipo de dados.

A concepção e optimização de co-processadores para a resolução de

tarefas computacionalmente intensivas têm vindo a ser abordada, num esforço

por dar resposta a problemas de engenharia concretos. O conhecido problema

SAT constitui um dos mais importantes por ter aplicação em diversas áreas, tais

como colocação e encaminhamento de circuitos electrónicos, síntese lógica, teste

5

de circuitos, planeamento, telecomunicações, matemática, robótica e arquitectura

de computadores [1].

1.2. Objectivos

Os principais objectivos deste projecto são:

• Criar uma biblioteca reutilizável de suporte à recursividade em

hardware;

• Implementar um modelo reutilizável de transferência de dados entre

computador anfitrião e co-processador, baseado na compressão de

dados, para optimização de largura de banda;

• Desenvolver um circuito eficiente, para a resolução do problema

combinatória SAT.

6

2. Plano de trabalhos

Tal como referido anteriormente, na realização de tarefas de grande

complexidade, a utilização de co-processadores com características mais

adequadas tem como objectivo reduzir o tempo da sua realização. No entanto,

perante tarefas que implicam grandes quantidades de dados, a largura de banda

do canal de transferência pode ser um factor limitativo da taxa de realização das

tarefas. Para não comprometer a utilidade do co-processamento, a comunicação

pode tornar-se mais rápida através da compressão dos dados, num modelo como

o ilustrado na figura 1.

Computador Anfitrião

Compressão

Dados originais

Dados comprimidos

Co-processador

Dados originais

Descompressão

Dados comprimidos

Figura 1 – Modelo de co-processamento baseado em compressão e descompressão de dados genéricos

Depois de os dados comprimidos se encontrarem no co-processador,

existe a possibilidade de operar directamente sobre eles ou de os descomprimir

7

previamente. No presente trabalho, foram realizadas as duas abordagens de

forma a as poder comparar.

2.1. Resumo da Primeira Abordagem

A primeira abordagem consistiu na implementação de um modelo, no qual

o computador anfitrião começa por comprimir os dados, utilizando um algoritmo

de compressão genérico, e enviá-los pela porta paralela ou interface ethernet.

Seguidamente, o co-processador efectua a descompressão, opera sobre os

dados originais e responde, devolvendo os resultados (de muito menor dimensão)

pelo mesmo canal de transmissão.

Procurou-se um algoritmo eficiente (com factores de compressão

elevados), simples (para ser rápido) e implementável em hardware de recursos

limitados. Assim, foi adoptada a versão adaptativa do algoritmo de Huffman, à

qual se integrou:

• Mecanismo de remoção da redundância em repetições consecutivas;

• Mecanismo limitador do tamanho da codificação dos símbolos.

Baseando-se em operações sobre dados organizados em árvore, o

algoritmo de compressão/descompressão de Huffman levou a implementações de

cariz recursivo. Se, por um lado, as linguagens de programação de software

permitem utilizar esta técnica trivialmente, nenhuma linguagem de especificação

de hardware inclui suporte à recursividade. Para dar resposta a este problema, foi

implementado o modelo RHFSM – Máquina de Estados Finitos Hierárquica

Recursiva [12]. Este modelo baseia-se na concepção das partes recursivas do

algoritmo na forma de máquinas de estados finitos. Para permitir alguma

abstracção no que diz respeito à gestão das variáveis de suporte às transições

entre estados e módulos, foi criada uma biblioteca simples e reutilizável,

denominada RHFSM.

8

Com o suporte à recursividade em hardware, tornou-se possível

implementar o parser para a interpretação da árvore de codificação Huffman que

precede os dados comprimidos.

2.2. Resumo da Abordagem Alternativa

Numa segunda abordagem, assente num compromisso relativamente ao

tipo de dados a transmitir para o co-processador, a forma de acelerar a

transferência consistiu em utilizar um formato comprimido específico e que não

implicasse descompressão.

O formato escolhido destinava-se a dados que representam matrizes

SAT3, ou seja, matrizes ternárias, tais como as matrizes SAT, com valores “0”, “1”

e dontcare, mas com um número máximo por linha de valores não dontcare igual

a 3. Estas matrizes podem ser obtidas através de uma conversão de ordem de

complexidade polinomial a partir de matrizes SAT comuns – tarefa atribuída ao

computador anfitrião.

Foi implementado um sistema SAT3-Solver na FPGA do co-processador,

que obtém o vector solução (caso exista), acedendo directamente aos dados

comprimidos. Porque o formato utilizado permite níveis de compressão muito

elevados e por se ter utilizado a interface ethernet, obtiveram-se tempos globais

de co-processamento significativamente reduzidos.

9

3. Ferramentas

3.1. FPGA utilizada

Como dispositivo lógico reprogramável foi utilizada a Virtex II XC2V1000 da

Celoxica. As principais características deste dispositivo são:

• 1280 CLBs (Configurable Logic Blocks) que permitem implementar

qualquer função Boolena de várias variáveis

• 720 Kbits de memória RAM mais 160Kbits de memória implementada

em CLBs (RAM distribuída)

• 8 DCMs (Digital Clock Managers) que permitem a síntese de um

domínio de relógio distinto

• Até 432 blocos de entrada/saída (I/O) que permitem a ligação da lógica

interna com os pinos externos da FPGA.

A explicação detalhada destes blocos encontra-se descrito em [2].

3.2. RC200

A placa protótipo utilizada para a realização de todos os testes foi a

RC200[3,4] da Celoxica apresentada na figura 2. Esta placa, possui além de uma

FPGA Virtex II XC2V1000-4[2] vários dispositivos que podem ser usados para

testar as potencialidades da FPGA:

• 2 memórias SRAM de 4Mbytes cada;

• Video In/Out;

• Audio In/Out;

10

• Smartmedia socket;

• 10/100 ethernet;

• Porta paralela;

• Porta RS232;

• Teclado & rato PS2;

• TFT display/touch screen ;

• Modulo Bluetooth wireless.

Figura 2 – Placa protótipo RC200

Apesar de no trabalho final apenas serem utilizados a FPGA, o módulo

ethernet e o display de sete segmentos durante a fase de desenvolvimento foram

utilizados outros periféricos. É caso disso o display TFT que durante uma fase

inicial foi utilizado como meio de output e a porta paralela cuja utilização chegou a

ser ponderada.

11

3.3. Handel-C

O Handel-C [5], é uma linguagem de alto nível baseada no ANSI-C que

permite o desenvolvimento de Sistemas Reconfiguráveis. Apesar de muitas das

construções serem partilhadas com o Ansi-C [6] o facto de esta se destinar a

outro domínio fez com que novas construções surgissem e com que algumas

existentes não pudessem ser utilizadas. A figura 3 ilustra isso mesmo.

ANSI-C Handel-C

- Virgula flutuante

- Paralelismo

- Macro expressions

- Macro procedures

- Variáveis detamanho nãopré-definido

- Interfaces

- RAM & ROM

- Canais

- Sinais

- Arrays

- Estruturas

- Directivas de pré compilação

- Operadores aritméticos (+,-,*,/,%)

- Operadores lógicos (&&, || !, ^, &,|)

- Construções do Ansi-C(for, while, if, switch)

- Funções

- Ponteiros

- Recursividade

- Side effects(i++, j--)

Figura 3 – Comparação entre o Ansi-C e o Handel-C

Esta linguagem tem como principal característica, relativamente às

linguagens de descrição de hardware, o facto de permitir uma maior abstracção

do hardware e consequentemente um menor tempo e custo de desenvolvimento.

12

3.4. Winpcap

O WinPcap [7] permite a captura de pacotes e a análise de redes em

plataformas Windows. Tipicamente as aplicações que fornecem primitivas para a

transferência de informação entre elementos da rede, fazem-no num alto nível, de

modo a facilitar a operação. Pelo contrário, o WinPcap fornece primitivas em C

que nos permitem programar no nível 2 do modelo OSI, possuindo as seguintes

funcionalidades:

• Captura todos os pacotes que passam na rede, independentemente do

PC destino/origem;

• Envio de pacotes definidos através sequências de bytes.

3.5. Fluxo de trabalho

O desenvolvimento de circuitos em Handel-C segue o fluxo ilustrado na

figura 4. Em primeiro lugar é utilizado o editor DK2 (Development Kit 2) [8] para a

edição do código Handel-C que vai especificar o circuito. Após esta fase o código

é compilado sendo obtido como resultado um ficheiro EDIF (Electronic Design

Interchange Format) [9]. Este ficheiro EDIF é aberto pelo ISE [10] com o objectivo

de ser compilado e consequentemente gerado o bitstream que através do

programa FTU (File Transfer Utility) [11] é carregado na FPGA. Após a anterior

sequência de passos a FPGA já tem implementado o dispositivo físico pretendido.

FTUISECódigoHandel-C

CódigoEDIF

BitStream

DK FPGA

Figura 4 – Fluxo de trabalho

13

4. Implementação de modelo de suporte à recursividade

Como referido anteriormente, a linguagem Handel-C não possui

mecanismos de suporte à recursividade. No entanto, com vista a se poder usar

algoritmos recursivos foi implementado o modelo RHFSM (Recursive Hierachical

Finite State Machine) definido por Sklyarov [12]. Este modelo tem como ideia

base a de modelar o algoritmo a implementar numa máquina de estados finitos.

Esta máquina de estados finitos é constituída por vários módulos, sendo cada

módulo constituído por estados que estão associados a conjuntos atómicos de

instruções. Segundo este modelo a execução do algoritmo corresponde a

sucessivas transições entre os estados dos módulos existentes.

O RHFSM é constituído por duas stacks: uma de identificadores de módulo

(stack de módulos); outra de identificadores de estado no contexto de cada

módulo (FSM stack). Para permitir alguma abstracção no que diz respeito à

gestão das stacks, foi criada uma biblioteca simples e reutilizável, denominada

RHFSM, que inclui sete primitivas em Handel-C de suporte às transições entre

estados e módulos:

RHFSM_init( ), que inicia os dados internos para se estar apto a usar a

RHFSM;

RHFSM_go_to( next_state ), que permite transitar para o estado

next_state do módulo activo;

RHFSM_jump_to( next_module, next_state ), que permite transitar para

o estado next_state do módulo next_module;

RHFSM_end_module( ), que permite a saída do módulo activo,

regressando ao módulo anterior ou terminando a RHFSM;

RHFSM_state( ), que devolve o estado activo;

RHFSM_module( ), que devolve o módulo activo;

14

RHFSM_done( ), que indica se a RHFSM terminou.

Do ponto de vista do utilizador, a utilização desta biblioteca implica a

estruturação do código numa máquina de estados e a fusão deste com as

anteriores funções que gerem os dados de suporte às transições.

Pretende-se mostrar um exemplo de como esta biblioteca pode ser

utilizada de modo a implementar um algoritmo que de uma forma recursiva

calcule o factorial. Na figura 5 está representada a sequência de eventos relativa

à execução do algoritmo, apresentando a parte útil do código, e na figura 6 o

código correspondente.

Início

Fim

Estado 0

fact *= n;n--;

n != 1

Estado 1

Início

Fim

Invocação doMódulo 0

Figura 5 – Sequência de eventos do algoritmo de calculo de factorial

Neste exemplo existe um único modulo que contém dois estados. No

estado 0 é obtido o valor do factorial para a iteração em questão, e reinvocado o

módulo sempre que a variável n seja maior que 1. No estado 1 é terminada a

execução do módulo.

15

do { par { module = rm_module(); /* controlo RHFSM */ state = rm_state(); /* controlo RHFSM */ } switch(module) { case 0: { switch(state) { case 0: { rm_go_to(1); /* controlo RHFSM */ fact*=n; /* código útil */ n--; /* código útil */ if(n!=1)

rm_jump_to(0,0); /* controlo RHFSM */ break; } case 1: { rm_end_module(); /* controlo RHFSM */ break; } } break; } } done=rm_done(); /* controlo RHFSM */ } while(!done);

Figura 6 – Código do algoritmo que calcula o factorial

16

5. Transmissão de dados

A utilização de FPGA’s como auxiliares do processamento do computador,

implica que informação tenha de ser trocada entre estes. De modo a não

comprometer o desempenho do sistema é desejável que a interface usada, seja

não só o mais rápida possível, como também a sua implementação deve ser

simples de modo a usar o número mínimo de recursos. Das interfaces

disponíveis, foi escolhida a ethernet, porque apesar da sua utilização ser um

pouco mais complexa do que a da porta paralela, a velocidade de transmissão de

100 Mbits da ethernet é em muito superior à da porta paralela que é de 1,6 Mbits.

A ethernet possui ainda a vantagem de a sua utilização ser distribuída, ou seja, de

uma mesma FPGA’s poder servir de co-processador para vários computadores.

Devido ao facto da ethernet funcionar de um modo distribuído, teve que ser

elaborado um protocolo de comunicação. Este protocolo foi construído por cima

do nível 2 (data) do modelo OSI, pois é este o nível mais elevado em que a

RC200 permite trabalhar. Do lado do PC, foi utilizada a aplicação WinPcap [7]

Com o objectivo não sub carregar a FPGA o protocolo tentou ser o mais

simples possível. Deste modo criou-se um protocolo em que a RC200 recebe

pacotes com pedidos de resolução de matrizes e envia pacotes resposta com a

solução da resolução.

Em ambos os pacotes os primeiros dois campos indicam respectivamente

o endereço MAC destino e origem e o terceiro o protocolo usado.

O quarto campo contém informação que depende do tipo de pacote

(Pedido/Resposta). No caso de ser um pacote “Pedido” este campo indica se a

matriz está contida num único pacote ou se teve que ser fraccionada em vários.

Esta informação é vital para a recuperação da matriz na placa.

No caso de ser um pacote “Resposta” este campo indica se foi ou não

possível resolver a matriz.

17

O campo “Tamanho” indica o tamanho dos dados enviados e os campos

“Nº Linhas” e “Nº Colunas” indica respectivamente o numero de linhas e de

colunas da matriz.

O campo Corpo da mensagem contém a matriz no caso de se tratar de um

pacote “Pedido” e o vector solução no caso de se tratar de um pacote “Resposta”.

Corpo da mensagem

MAC Destino(6 bytes)

Protocolo(2 bytes)

Nº Linhas(2 bytes)

MAC Destino(6 bytes)

Tipo(1 byte)

Tamanho(2 bytes)

Nº Colunas(2 bytes)

Figura 7 – Formato dos pacotes enviados/recebidos

Apesar da ethernet ter velocidades de transmissão de 100Mbits, devido às

limitações da capacidade do envio/recepção de dados, e ao overhead produzido

pelo cabeçalho as velocidades de transmissão obtidas ficaram em muito aquém

deste valor. Por exemplo, para enviar uma matriz ternária de 256 x 256 (131.072

bits) são necessários 3,310 ms o que corresponde a uma velocidade de 39 Mbits.

No entanto, apesar deste valor ser inferior ao esperado, este é em muito superior

ao de outras interfaces.

18

6. Tarefa de Co-processamento: SAT

A tarefa de co-processamento escolhida neste projecto pretende dar

resposta ao problema de satisfação booleana [1] (SAT) que consiste na procura

de um vector que satisfaça expressão booleana. No desenvolvimento de SAT-

solvers, é possível traduzir estas expressões booleanas em matrizes ternárias,

nas quais, cada linha corresponde a uma dada restrição [1].

Tendo os dados do problema expressos na forma de uma matriz ternária, o

objectivo da tarefa traduz-se em encontrar um vector que seja ortogonal com

todas as linhas/vectores dessa matriz. Para tal, considera-se que dois vectores

são ortogonais se existir pelo menos um índice cujo valores correspondentes

sejam não dontcare e diferentes.

É possível implementar esta tarefa, recorrendo à aplicação de regras de

redução e selecção à matriz, e a eventuais retrocessos [1], até que todas as

linhas sejam ortogonais com o vector solução.

A regra de redução é aplicada sempre que numa coluna de uma linha

apenas exista um único valor não dontcare. Neste caso é atribuído o valor

contrário na posição correspondente do vector auxiliar e a coluna é eliminada.

A regra de selecção é aplicada sempre que toda a matriz tenha sido

percorrida sem que nenhuma regra de redução tenha sido aplicada. Neste caso é

seleccionada uma coluna da matriz que corresponda a um valor não dontcare no

vector auxiliar e é-lhe atribuído o valor de ‘0’ ou de ‘1’, sendo a linha eliminada.

A aplicação da regra de selecção, em determinadas condições, pode

implicar no comprometimento da obtenção de uma solução, em casos de matrizes

que expressam problemas resolúveis. Assim, torna-se necessário um mecanismo

de retrocesso, que permite voltar a uma situação anterior, para que sejam

experimentados outros caminhos, na árvore de pesquisa, e encontrado um vector

solução.

19

7. Modelo baseado em Compressão e Descompressão

Esta primeira abordagem consistiu na implementação de um modelo de

transferência de dados entre um PC e a placa protótipo RC200 baseado num

algoritmo de compressão de dados genéricos.

7.1. Escolha e descrição do algoritmo de compressão

Na escolha do algoritmo de compressão/descompressão a implementar

[12,13], foram considerados principalmente três critérios:

• Eficiência, para fornecer factores de compressão elevados;

• Simplicidade, para comprimir e descomprimir em tempo reduzido;

• Implementabilidade em hardware com recursos limitados.

7.2. Algoritmo de Compressão de Huffman

O algoritmo de compressão de Huffman assenta no facto de, num mesmo

ficheiro, a frequência com a qual os símbolos aparecem poder variar muito.

Frequentemente, grande parte da gama representável pelo número de bits da

codificação utilizada nem sequer é utilizada. Assim, a compressão deste algoritmo

baseia-se em tornar mais curtas a codificação dos símbolos mais frequentes,

facto que implica a atribuição de codificações mais longas aos mais raros.

Na versão mais simples deste algoritmo, a frequência de cada símbolo é

determinada uma só vez, a partir de estudos estatísticos, pelo que se utiliza uma

20

codificação fixa. Na versão adaptativa, por outro lado, a codificação resulta da

determinação das frequências dos símbolos prévia a cada compressão realizada.

Assim, há que associar a cada ficheiro comprimido a respectiva codificação

Huffman.

Por ir ao encontro dos critérios estabelecidos em medida considerável, foi

adoptada a versão adaptativa do algoritmo de compressão de Huffman [13, 14,

15], na qual, porém, se realizaram algumas adaptações, nomeadamente a

integração de dois mecanismos:

• Mecanismo de remoção da redundância em repetições consecutivas;

• Mecanismo limitador do tamanho da codificação dos símbolos.

O primeiro mecanismo consiste em detectar repetições consecutivas,

indicar a sequência de bits em causa, uma única vez, e indicar o número de

repetições. Consequentemente, a contagem das ocorrências de cada símbolo

para a sua ordenação e a posterior geração da codificação, passa a considerar

apenas as ocorrências não consecutivas.

O segundo mecanismo surgiu da necessidade de estabelecer uma

profundidade máxima para a árvore de codificação de Huffman, tendo em vista a

sua conversão para o formato de tabela no circuito de hardware que realizaria a

descompressão.

Em seguida, é descrito o funcionamento da aplicação desenvolvida,

ilustrando os passos envolvidos na criação dos ficheiros comprimidos.

Considerando o exemplo do ficheiro na figura 8-a, o primeiro passo

consiste em determinar o número de ocorrências e o tamanho da sequência mais

longa de repetições consecutivas de cada caracter, criando a tabela de frequência

presente na figura 8-b. Seguidamente, para cada caracter, é criado um nó com o

respectivo número de ocorrências. Recorrendo a um algoritmo de ordenação

(considerado em [6]), é gerada uma árvore (figura 8-c) cuja organização exprime

a ordenação dos nós por número de ocorrências: ramo esquerdo para valores

menores ou iguais; ramo direito para valores maiores. Esta árvore, designada de

árvore de ordenação, permite obter a árvore de Huffman, através de algumas

transformações cuja descrição se segue.

21

1000011 1000010 1000011 100010010001001000100B B CCCA

Ficheiro Original

1000010 1000011 1000100A B C1

Sequência de bits originalCaracter representadoNº. de ocorrências não consecutivas 2 1

Tabela de Frequência

Árvore de Ordenação

C1

B2

A1

Tamanho da maior sequência de repetições consecutivas 11 3

B2

Árvore de Huffman:

ABC

0 0

Caracter: Codificação:

10 1

Tabela de Codificação:

B B C C C

x 3C

A

1 00 1 01 11

Ficheiro Comprimido:

A1

C1

AC2

A1

C1

AC2

B2

ABC3

0

0

1

1

B2

A1

C1

AC2

a)

b)

c) d)

e)

f)

g)h)

Figura 8 – Exemplo de aplicação do algoritmo de compressão

Nas figuras 8-c, 8-d, 8-e e 8-f, as ligações que representam os ramos das

árvores de ordenação e de Huffman estão representadas por linhas contínuas e

descontínuas, respectivamente. O processo é cíclico e o primeiro passo consiste

em retirar da árvore de ordenação os dois nós com menor valor. Estes nós são

agregados num novo nó, ao qual se atribui o valor da soma dos números de

22

ocorrências dos nós anteriores, obtendo um ramo na árvore de Huffman (figuras

8-c e 8-d). O novo nó é inserido na árvore de ordenação (figura 8-e) e todo este

conjunto de operações é repetido até que existam apenas ligações da árvore de

Huffman (figura 8-f). Este método de transformação é descrito com maior detalhe

e acompanhado de um exemplo mais complexo, por Valery Sklyarov, no artigo

“FPGA-based implementation of recursive algorithms” [16].

Fazendo uso dos valores 0 e 1, para distinguir os ramos da esquerda e da

direita em cada nó da árvore de Huffman, é possível construir a tabela de

codificação dos caracteres apresentada na figura. 8-g. Para tal, é extraída a

sequência de valores que se obtém no caminho desde a raiz até à folha de cada

caracter. Como exemplo, a codificação 01 para o caracter C justifica-se pelo facto

de a folha correspondente se encontrar no ramo direito do nó AC que, por sua

vez, pertence ao ramo esquerdo do nó ABC.

Finalmente, recorrendo à tabela de codificação, é possível realizar a

tradução dos caracteres originais pelos códigos correspondentes.

Na descompressão, é realizada a tradução no sentido inverso, utilizando,

novamente, a tabela de codificação. Em caso de sequência de repetições

consecutivas, é lido o tamanho da mesma, de modo a poder reconstitui-la.

23

7.3. Implementação do Compressor e Descompressor em C++

Se no passo anterior foi realizada uma descrição do funcionamento do

algoritmo de Huffman, neste tópico é mostrada a forma como este foi

implementado.

Foi considerado o caracter como elemento básico da compressão, cujo

tamanho é oito bits. No entanto, foi introduzido o conceito de símbolo, enquanto

elemento básico de compressão de tamanho não pré-definido, possibilitando uma

eventual optimização do factor de compressão.

A versão adaptativa realiza uma optimização ao algoritmo de Huffman

original, através da definição da codificação individual dos símbolos para cada

ficheiro a comprimir. Uma vez que esta codificação é necessária ao descomprimir,

definiu-se que a árvore de Huffman gerada na compressão seria incluída no início

do ficheiro, ficando toda a informação necessária à descompressão a ele

confinada. Sendo assim, antes de iniciar a implementação do algoritmo,

especificou-se o formato a utilizar no armazenamento da árvore, assegurando a

compatibilidade entre as componentes.

Para especificar a estrutura de armazenamento da árvore de Huffman no

ficheiro comprimido, foi utilizada a norma BNF (Backus Naur Form) [17]. Na figura

9 é apresentada uma versão simplificada da especificação definida, tendo alguns

parâmetros sido concretizados.

24

<Bit>::=0|1

<Simbolo>::=<Bit><Bit><Bit><Bit><Bit><Bit><Bit><Bit>

<TamanhoRepeticao>::=<Bit><Bit><Bit><Bit>

<Folha>::=<TamanhoRepeticao><Simbolo>

<Ramo>::=0<Folha>|1<Ramo><Ramo>

<ArvoreHuffman>::=<Ramo>

Figura 9 – Estrutura de armazenamento da árvore de Huffman

Segundo esta especificação, a árvore de Huffman é constituída por um

ramo, podendo cada ramo conter uma folha ou um par de ramos. As folhas são

constituídas por um símbolo e pelo número de bits que vão indicar o número

máximo de repetições consecutivas. Neste exemplo, foram atribuídos quatro bits

para o tamanho máximo de repetições consecutivas e oito para o de símbolo.

7.3.1. Compressor em C++

O processo de compressão é constituído pelas seguintes fases: definição

da codificação a utilizar através da análise do ficheiro original, exportação da

árvore de Huffman e tradução efectiva do ficheiro.

Como referido, a codificação atribuída a cada símbolo do ficheiro original

baseia-se no número de vezes que nele ocorre. Assim, é feita uma primeira leitura

para o levantamento desta informação e para verificar o maior Número de

Ocorrências Consecutivas (NOC) de cada símbolo.

Os NOC’s máximos vão ser utilizados na determinação do número de bits

necessário para armazenar o tamanho das repetições consecutivas de cada

símbolo, que foram detectadas nos dados comprimidos. O diagrama de

actividades que consta da figura 10 descreve o funcionamento desta análise.

25

Início

Fim

Fim doficheiro?

[Não]

Símboloactual é igual ao

anterior?

NOC maiordo que o armazenado

como máximo?

[Sim]

Ler Símbolo

Actualizar NOC Máximodo Símbolo anterior

[Não]

Limpar NOC no casode Símbolo novo

[Sim]

[Sim]

Incrementar NOCdo Símbolo

Incrementar Número deOcorrencias do Símbolo

[Não]

Figura 10 – Diagrama de actividades do processo de análise do ficheiro original

Iterativamente até ao fim do ficheiro, é lido um símbolo que é comparado

com o anterior. Se estes símbolos forem iguais, o NOC actual (variável auxiliar) é

incrementado; se se tratar de um novo símbolo, incrementa-se o número de

ocorrências deste.

De seguida, o NOC actual é comparado com o NOC máximo do símbolo

em causa (armazenado na tabela de frequência). No caso de o primeiro ser

superior, o segundo é actualizado.

No passo seguinte, o NOC actual é inicializado, no caso de se tratar de um

símbolo novo, uma vez que se trata do começo de uma nova sequência.

A informação obtida da anterior análise do ficheiro de entrada é utilizada

para a criação da árvore de ordenação. Para tal, cada símbolo com número de

ocorrências positivo dá origem a um nó que é inserido na árvore de ordenação [5].

Como ilustrado nas figuras 8c-f, esta árvore é convertida na árvore de Huffman, a

partir da qual se extrai a codificação de cada símbolo, populando a tabela de

codificação.

26

A exportação da árvore de Huffman consiste na invocação de uma função

recursiva, reinvocando-se para exportar cada um dos ramos até às folhas, e

verificando o formato que foi previamente especificado (figura 9).

Por último, é realizada a tradução dos símbolos do ficheiro original para a

codificação definida, através de uma segunda leitura. O diagrama de actividades

que consta da figura 11 descreve os passos envolvidos neste processo. Cada

símbolo lido é comparado com o anterior para verificar se se trata da mesma

sequência de repetição. Em caso afirmativo, o NOC é incrementado e passa-se

ao símbolo seguinte. Ao detectar-se uma nova sequência, são exportados a

codificação do símbolo anterior e o NOC obtido, sendo ambos actualizados para a

sequência seguinte.

Início

Fim

Fim doficheiro? [Não]

Símboloactual é igual ao

anterior?

[Sim]

Ler Símbolo

[Sim]

[Sim]

Incrementar NOCdo Símbolo actual

Limpar NOC para oSímbolo actual [Não]

Exportar NOC doSímbolo anterior

Exportar Codificaçãodo Símbolo anterior

Fim doficheiro?

[Não]

Figura 11 - Diagrama de actividades do processo de tradução na compressão

27

7.3.2. Descompressor em C++

O processo de descompressão é constituído pela importação da árvore de

Huffman e pela tradução dos códigos nos símbolos do ficheiro original.

A importação da árvore de Huffman consiste em interpretar a sequência

binária que precede os dados comprimidos, no ficheiro. Para tal, é usada uma

função recursiva, que se reinvoca para a importação de cada um dos ramos, até

às folhas, tendo em conta o formato especificado para o efeito (rever figura 9).

A tabela de codificação, obtida com a interpretação da árvore de Huffman,

é utilizada na reconstituição dos símbolos originais. Este processo, ilustrado na

figura 12, inicia-se com a leitura de um código que corresponde a um símbolo. Se

esse símbolo envolver NOC, é lido o seu valor do ficheiro comprimido; caso

contrário, assume-se que é unitário.

Por último, o símbolo em causa é repetido no ficheiro de saída o número

de vezes indicado pelo valor de NOC. O ciclo repete-se até que o ficheiro

comprimido termine.

Início

Fim

Fim doficheiro?

[Não]

EnvolveNOC?

[Sim]

Ler Código

[Não][Sim]

Decrementar NOC Escrever Símboloassociado ao Código

[Não]

Ler NOCNOC

positivo?NOC = 1

[Sim]

Figura 12 - Diagrama de actividades do processo de tradução na descompressão

28

7.4. Implementação do Descompressor em Handel-C

Foi desenvolvido um algoritmo em Handel-C [5] que realiza uma

descompressão idêntica à que foi feita em C++. De notar que os algoritmos

criados numa e noutra linguagem revelam diferenças significativas, uma vez que

assentam em paradigmas bastante distintos: um é orientado aos objectos, o outro

é funcional e de especificação de hardware. A possibilidade de execução de

operações em paralelo permitiu optimizar o processo de descompressão,

aumentando a velocidade de execução. No entanto, a diferença mais significativa

entre as duas implementações proveio da utilização do modelo RHFSM

(Recursive Hierarquichal Finite State Machine) [16]. Com este modelo,

ultrapassou-se a ausência de mecanismos de suporte à recursividade das

linguagens de especificação de hardware. O capítulo 4 aborda a implementação

deste modelo.

O funcionamento global do circuito descompressor está ilustrado na figura

13. O cabeçalho do ficheiro comprimido (figura 13-a) é lido através do Gestor de

Leitura, para o parser que interpreta a árvore de Huffman e reconstrói a Tabela de

Codificação (figuras 13-a, 13-c, 13-d e 13-e). A segunda fase da descompressão

consiste em ler os dados comprimidos através do Gestor de Leitura e traduzi-los

nos caracteres originais, recorrendo à Tabela de Codificação (figuras 13-b, 13-c e

13-f). Os caracteres obtidos são escritos, reconstituindo o ficheiro original, através

do Gestor de Escrita (figuras 13-h e 13-g).

29

Parser daÁrvore deHuffman

Tradutor Código/Caracter

Ficheiro Descomprimido

Ficheiro Comprimido

Tabela deCodificação

Gestor de Leitura doFicheiro Comprimido

Gestor de Escrita noFicheiro Descomprimido

a) b)

c)

d)

g)

e)

h)

f)

Figura 13 – Circuito descompressor em Handel-C

Estando o suporte à recursividade definido (capitulo 4), o passo seguinte

consistiu em modelar o parser na forma de uma máquina de estados finitos

hierárquica. Como foi referido, a finalidade do parser é interpretar a árvore de

Huffman que se encontra no início do ficheiro, armazenada de acordo com o

definido em código BNF (figura 9).

Para uma análise pormenorizada da implementação do parser, o código

Handel-C respectivo está disponível no site da WebCT [18]. Na figura 14, é

descrito o fluxo do parser, através dos estados e transições que compõem o

módulo implementado. O processo é iniciado, invocando este módulo.

30

Begin

x1 z0

a1

a2

[1]

a5

a0

End

z0

a3

Módulo z0

a4

[0]

Figura 14 - Módulo da RHFSM do parser

No estado a0, é lido um nó do ficheiro comprimido. Na condição x1, é

verificado se o nó é uma folha ou um ramo.

No caso de ser folha, transita-se para o estado a1, no qual se extrai o

número de bits para o NOC e o símbolo que foram armazenados na folha.

Seguidamente, transita-se para o estado terminal a5, após o qual, se retorna ao

nível hierárquico superior.

Se na condição x1, por outro lado, se verificar que o nó lido representa um

ramo, transita-se para o estado a2. Neste estado, é reinvocado o módulo z0,

descendo-se de nível hierárquico, para realizar o parsing do ramo esquerdo do

nó.

Após regressar desta sub-tarefa, retoma-se o nível hierárquico anterior e

transita-se para o estado a3. Neste estado, repete-se a invocação do módulo z0,

para realizar o parsing do ramo direito.

31

Ao concluir-se a importação do segundo ramo deste nó, regressa-se ao

estado a4, realizando algumas operações auxiliares, e transita-se para o estado

terminal a5.

7.5. Resultados das experiências com o modelo de transferência implmentado

Foram realizadas diversas experiências integrando a compressão realizada

no computador de uso geral, a transmissão via ethernet e o circuito de

descompressão configurado na FPGA. Os dados utilizados foram colecções de

matrizes ternárias com dimensões 128 x 128, 128 x 500, 256 x 256, 256 x 1000 e

256 x 1500 (colunas x linhas).

Dimensões da Matriz

(nº colunas × nº linhas)

TT (ms)

Recursosda FPGAutilizados

RácioTTaC

(ms)

TC (ms)

TD (ms)

TTaC + TD (ms)

128 × 128 0.903 0.130 0.117 20 0.943 1.060

128 × 500 3.310 0.139 0.460 220 3.800 4.260

256 × 256 3.310 0.105 0.347 60 3.715 4.062

256 × 1000 12.940 0.087 1.126 230 15.380 16.506

256 × 1500 19.260

12 %

0.077 1.483 872 23.024 24.507

Tabela 1 – Resultados das experiências

Legenda: TT – Tempo médio de Transmissão sem Compressão TTaC – Tempo médio de Transmissão após Compressão TC – Tempo médio de Compressão (no PC anfitrião) TD – Tempo médio de Descompressão (na placa RC200)

A análise da tabela 1 revelou que, apesar de terem sido obtidos factores de

compressão elevados, o tempo total implicado na transferência dos dados,

32

fazendo uso da compressão implementada, foi superior ao tempo relativo à

transferência simples. De facto, mesmo não considerando o tempo de

compactação, por esta poder ser realizada em simultâneo com o co-

processamento, a soma do tempo de transmissão após compressão com o tempo

de descompressão foi superior ao tempo de transferência simples. No entanto, há

que ter em conta que o canal de transferência utilizado foi uma interface ethernet,

canal este de elevada largura de banda.

Tendo em conta os rácios obtidos, é possível prever uma optimização

substancial dos tempos de transferência que o modelo implementado traria,

utilizando interfaces de comunicação mais lentas. Este facto, ilustrado no gráfico

da figura 15, justifica-se na medida em que, para tempos de transmissão

superiores, o tempo de descompressão torna-se menos relevante para o tempo

de transferência.

Tempo deTransferência

TTaC+TD

TT

TTaC

TD

Largura de Banda -1

Figura 15 – Tempo de transferência simples e após compressão com o aumento da largura de banda

Utilizando, por exemplo, a porta paralela como canal de transmissão, uma

vez que os tempos de transmissão simples e após compressão (TT e TTaC,

33

respectivamente) seriam aproximadamente 10 vezes superiores, o tempo de

transferência com o modelo implementado (TTaC+TD) seria, para qualquer dos

exemplos apresentados, inferior relativamente a uma transferência simples.

Ao completar a implementação do modelo de transferência desta primeira

abordagem e tendo obtido uma solução aplicável na optimização de canais de

transmissão de largura de banda reduzida, urgiu apostar numa compressão mais

eficiente e na optimização da própria realização de tarefas realizadas pelo co-

processador.

34

8. Abordagem alternativa: formato comprimido

Como foi visto, a implementação de um modelo de transmissão de dados

baseado na compressão genérica apenas se revelou vantajoso para larguras de

banda reduzidas. Tendo disponível um canal de transmissão com uma taxa de

transmissão elevada, como a interface ethernet, o bottleneck de todo o processo

passa a ser o processamento associado à compressão e descompressão dos

dados. Deste modo, tornou-se oportuna a adopção de um modelo no qual fosse

possível operar directamente sobre os dados num formato comprimido,

eliminando o overhead que o modelo anterior apresenta. Este modelo está

representado na figura 16.

SAT solver

Resultados Resultados

Matriz noformato CS3M

Matriz noformato CS3M

Ethernet

RC200PC Anfitrião

Figura 16 – Modelo de co-processamento considerado na abordagem alternativa

35

8.1. Formato comprimido para matrizes SAT3: CS3M

Na procura de um formato de armazenamento de matrizes ternárias com

grande factor de compressão, tirou-se proveito de uma propriedade destas

matrizes. É sabido que qualquer matriz ternária que expressa um problema de

SAT, cujas linhas possuem um número de valores não dontcare, é traduzível

numa outra, apresentando no máximo 3 valores não dontcare por linha,

continuando a expressa o problema original. Partindo desta propriedade, foi

possível definir um formato específico para as linhas de matrizes SAT3 que

elimina toda a redundância associada aos valores dontcare.

O formato em causa, denominado CS3M (Compressed SAT3 Matrix), é

ilustrado na figura 17, na qual as dimensões visam matrizes até 256 colunas.

O primeiro campo – Número de Índices Activos (NIA) – indica o número de

valores não dontcare da linha em causa, utilizando 2 bits, uma vez que o seu

valor máximo é 3.

Para cada um dos 3 possíveis valores não dontcare, existe um campo de

índice que indica o número da coluna associada e um campo de valor, apenas

com 1 bit, que indica se se trata de um ‘0’ ou de um ‘1’. O número de bits dos

campos de índice limita o tamanho máximo das colunas da matriz de acordo com

a expressão:

INDICEBITSNCOLSMAXN __2__ = .

NIA Índice 1 V 1 Índice 3 V 3Índice 2 V 2

2 bits 8 bits 1 bit 8 bits 1 bit 8 bits 1 bit

Figura 17 – Formato comprimido específico para matrizes SAT3

Mesmo nos casos em que o número de índices activos é inferior a 3, todos

os campos se mantêm presentes, sendo ignorados os que não são necessários.

36

Este compromisso permite que o circuito hardware não se torne demasiado

complexo no acesso aos dados, implicando um desperdício pouco significativo de

espaço de armazenamento.

O número de bits para cada linha, neste formato, em função do número

máximo de colunas pretendido é:

NMaxColsNBitsLinhaComp 2log*35+= .

Relativamente ao formato não comprimido, no qual são utilizados 2 bits

para cada valor (‘0’, ‘1’ ou dontcare), o número de bits para cada linha é:

NColsNBitsLinhaNComp *2= .

O circuito ilustrado na figura 18 demonstra como foi implementado o

acesso aos campos das linhas da matriz, processando-as sem descompressão ou

qualquer outro tipo de transformação.

NIA Índice 1 V 1 Índice 3 V 3Índice 2 V 2

MUX 1

Más

cara

de

Col

unas

MUX 2 MUX 3

Figura 18 – Circuito de acesso à linha a processar

37

8.2. SAT3-Solver-Core

O processo de procura do vector solução, descrito na figura 19, é iniciado

quando a matriz se encontrar armazenada na FPGA.

Início

Fim

Terminar = VERDADEIRO?

Inicializar

Processar Linha

ActualizarLinha

[Sim] [Não]

Actualizar Númerode Linha

Figura 19- Processar matriz

Após uma inicialização que inclui uma primeira leitura de linha da matriz,

começa um ciclo, no qual se processam as linhas de forma iterativa, até que a

flag de conclusão esteja activa. Em cada iteração, é processada uma linha de

acordo com o descrito na figura 20 e são actualizados a linha actual e respectivo

índice, em paralelo.

38

Início

Fim

CLO = NLM ?

[Não]

LinhaActual éortogonal?

LinhaActualtem apenas 1 valor não

dontcare?

CLI = NLM ?

Condição paraRetrocesso?

CLO = 0

Resultado = SUCESSOTerminar = VERDADEIRO

Incrementar CLOIncrementar CLI

Redução

Retrocesso

Selecção[Sim]

[Sim]

[Sim]

[Sim]

[Sim]

[Não]

[Não]

[Não]

[Não]

Figura 20 - Processar linha

O processamento de cada linha assenta num encadeamento de testes que

permite verificar qual a situação em que se enquadra, de acordo com o algoritmo

descrito pelos seguintes passos:

• Se o Contador de Linhas Ortogonais (CLO) tiver atingido o Número de

Linhas da Matriz NLM), ou seja, se todas as linhas da matriz forem

ortogonais com o actual Vector Solução, a flag de conclusão é activada

e à variável “Resultado” é atribuído o valor indicador de sucesso.

39

• Se a Linha Actual for ortogonal com o actual Vector Solução, o

Contador de Linhas Ortogonais e o Contador de Linhas Intactas (CLI)

são incrementados.

• Não se tratando dos casos anteriores, o Contador de Linhas Ortogonais

é inicializado, após o que o encadeamento de testes continua:

• Se a Linha Actual tiver apenas uma coluna com valor não dontcare, os

respectivos índice e valor são utilizados para aplicar a regra de redução

(abordada no capítulo 6). À coluna em causa, no Vector Solução, é

atribuído o valor ‘0’ ou ‘1’, de forma a obter ortogonalidade com a Linha

Actual.

• Se se verificarem as condições para um retrocesso, é invocada uma

rotina cujo algoritmo é descrito na figura 21. O retrocesso torna-se

necessário quando se verifica pelo menos uma das seguintes

condições:

o A Linha Actual não é ortogonal com o actual Vector Solução e

contém apenas valores dontcare nas colunas não mascaradas,

i.e., ainda não definidas naquele vector;

o A Profundidade Actual na Árvore de Pesquisa por Selecção

atingiu o seu valor máximo (o número de colunas da matriz).

40

Início

Fim

Foram jáexperimentados ambos

os Valores?

[Sim]

[Não]

Experimentaro valor ainda nãoexperimentado

ProfundidadeNa Árvore de Pesquisa por

Selecção = 0 ?

Resultado = FAILURETerminar = VERDADEIRO

Repôr o vectorsolução anterior à aplicação

da regra de selecção

CLI = 0

Fim

DecrementarProfundidade da Árvore de

Pesquisa por Selecção

[Sim]

[Não]

Figura 21- Retrocesso

• Se o Contador de Linhas Intactas tiver atingido o Número de Linhas da

Matriz, ou seja, se todas as linhas da matriz tiverem sido consultadas

sem gerar alterações no Vector Solução, é aplicada a regra de selecção

(abordada no capítulo 6). Para tal, é escolhida a primeira coluna do

actual Vector Solução cujo valor ainda não foi atribuído e é-lhe atribuído

um valor não dontcare. O Contador de Linhas Intactas é inicializado.

Para suportar um eventual retrocesso à situação anterior, no caso de

esta selecção não permitir encontrar uma solução, o Vector Solução é

previamente copiado para a seguinte posição na Pilha de Vectores

Solução e a Profundidade Actual na Árvore de Pesquisa por Selecção é

incrementada.

41

8.3. Incorporação de Gestor de Comunicação

Para completar o modelo de co-processamento descrito, foi criado um

Gestor de Comunicação. Este circuito controla a troca de dados entre a RC200 e

o computador anfitrião, através da interface ethernet, como ilustrado na figura 22.

De uma forma simplificada, é possível considerar três interfaces apresentadas

pelo Gestor de Comunicação:

• Para o Controlador de ethernet;

• Para o SAT3-Solver-Core;

• Para as variáveis partilhadas.

GestorComunic.

SAT3SolverCore

Vector solução

RC200

Controladorde Ethernet

PC Anfitrião Linhasda Matriz

FPGA

Figura 22 – Topologia das componentes do sistema implementado

O circuito do Gestor de Comunicação utiliza o Controlador de ethernet,

praticando um protocolo muito simples de transferência de dados. Este protocolo

foi denominado CS3MTP (Compressed SAT3 Matrix Transfer Protocol) que foi

também implementado, em C++, no computador anfitrião.

42

O circuito nuclear do SAT3-Solver comunica com o Gestor de

Comunicação, para efeitos de sincronismo, através de dois canais:

“MatrizRecebida” e “MatrizProcessada”.

Ao receber os pacotes transportadores de uma matriz, enviados pelo

computador anfitrião, o Gestor de Comunicação vai armazenado as linhas no

array partilhado para o efeito. Quando toda a matriz se encontra armazenada, é

utilizado o canal “MatrizRecebida” para que o SAT3-Solver-Core inicie. Acedendo

às linhas naquele array, o Vector Solução vai sendo alterado, até o processo

terminar. Nessa altura, o canal “MatrizProcessada” é utilizado para informar o

Gestor de Comunicação do sucesso ou insucesso, na procura do Vector Solução,

variável esta também partilhada por ambos os circuitos. No caso de insucesso, é

enviado um pacote somente com essa indicação para o computador anfitrião;

caso contrário, o Gestor de Comunicação acede ao vector solução e inclui-o na

resposta enviada.

8.4. Resultados das experiências com o SAT3-Solver

Foram realizadas diversas experiências com o SAT3-Solver, processando

matrizes resolúveis e irresolúveis, de 5 classes de dimensões, para fazer o

levantamento dos tempos necessários para a obtenção do resultado após a

matriz se encontrar na FPGA.

Foram geradas duas versões do circuito do SAT3-Solver, suportando

matrizes com dois valores máximos de colunas distintos: 128 e 256. As

respectivas percentagens de recursos da FPGA utilizados são apresentados na

tabela 2, juntamente com as médias das medidas temporais referidas. A geração

de uma terceira versão do circuito SAT3-Solver, visando suportar matrizes com

512 colunas, revelou necessitar de pouco mais recursos do que os disponíveis na

FPGA utilizada.

43

Tempo médio até obtenção

do resultado (ms) Dimensão das Matrizes

Recursosda FPGAUtilizados Matrizes

Resolúveis Matrizes

Irresolúveis

128 x 128 0.87 104

128 x 500 4.38 127

256 x 256

30 %

3.57 149

256 x 1000 7.09 195

256 x 1500 54 %

10.14 264

Tabela 2 – Resultados das experiências com o SAT3-Solver

Os tempos médios até obtenção de resultado para matrizes resolúveis e

irresolúveis foram apresentados de forma independente, uma vez que

apresentam ordens de grandeza significativamente diferentes. Este facto justifica-

se na medida em que a árvore de pesquisa vai sendo toda percorrida, enquanto

não for obtido um vector solução. Assim, com matrizes irresolúveis, toda a árvore

é percorrida enquanto que, com matrizes resolúveis, o vector solução é

encontrado com a ajuda da heurística subjacentes à regra de redução.

44

9. Conclusões

Com o objectivo de optimizar um sistema de co-processamento, foram

abordados dois modelos:

• O primeiro baseado na compressão e descompressão de dados

genéricos;

• O segundo baseado num formato comprimido específico, sobre o qual

se pode operar directamente.

Criou-se uma biblioteca Handel-C de suporte à recursividade, que

implementa o modelo RHFSM. Esta biblioteca foi utilizada para implementar o

parser que integra o circuito descompressor.

Implementou-se um modelo de transferência de dados genéricos entre

computador anfitrião e co-processador, com compressão e descompressão

baseadas na versão adaptativa do algoritmo de Huffman, na qual foram

integrados os seguintes mecanismos:

• Remoção da redundância em repetições consecutivas;

• Limitador do tamanho da codificação dos símbolos.

A implementação do modelo com compressão de dados genéricos revelou-

se vantajosa apenas para larguras de banda baixas, tais como a da porta

paralela.

Na segunda abordagem, definiu-se um formato comprimido específico para

matrizes SAT3, o qual permite operar directamente sobre estas, apresentando

factores de compressão muito elevados.

Implementou-se um SAT3-Solver de grande eficiência que suporta

matrizes até 256 colunas. A percentagem de recursos da FPGA utilizados por

este circuito permite prever a possibilidade de optimização para matrizes até 512

colunas.

45

10. Referências

[1] Iouliia Skliarova, “Arquitecturas reconfiguráveis para problemas de optimização

combinatória”, Dissertação de Doutoramento, Universidade de Aveiro, Janeiro,

2004, Cap. 6.3;

[2] “Virtex™-II Platform FPGAs:Introduction and Overview”, Xilinx, 2002;

[3] “RC200 Hardware and Instalation Manual”, Celoxica, 2003;

[4] “RC200 Platform Support Library Reference Manual”, Celoxica, 2003;

[5] “Handel-C Language Reference Manual”, Celoxica, 2002;

[6] Brian W. Kernighan, Dennis M. Ritchie, “The C Programming Language”, Prentice Hall,

1988;

[7] “Packet Capture Architecture for Windows”, [Online, em Junho de 2004]:

http://winpcap.polito.it;

[8] “DK Design Suite User Guide”, Celoxica, 2003;

[9] “Electronic Design Interchange Format”, [Online, em Junho de 2004]:

http://www.edif.org;

[10] “ISE - Design Tool”, [Online, em Junho de 2004]: http://www.xilinx.com/ise

[11] “FTU 2 User Guide”, Celoxica, 2003;

[12] V. Sklyarov, “Hierarchical Finite-State Machines and Their Use for Digital Control”,

IEEE Transactions on VLSI Systems, 1999, Vol. 7, No 2, pp. 222-228;

[13] “Data compression information” [Online, em Janeiro de 2003]:

http://datacompression.info;

[14] “Archive compression tests”, [Online, em Janeiro de 2004]: http://compression.ca/;

46

[15] “Lossless Data Compression”, [Online, em Junho de 2004]: http://www.data-

compression.com/lossless.html#huff;

[16] V. Sklyarov, “FPGA-based Implementation of Recursive Algorithms”, Elsevier Journal

Microprocessors and Microsystems, Abril, 2004;

[17] “BNF Notation”, [Online, em Junho de 2004]: http://cui.unige.ch/db-

research/Enseignement/analyseinfo/AboutBNF.html;

[18] Web Course Tools para a disciplina de Computação Reconfigurável leccionada na

Universidade de Aveiro, [Online, em Junho de 2004]: http://webct.ua.pt.

10.1. Publicações baseadas neste estudo

O estudo realizado no âmbito deste projecto final de curso contribuiu para a

realização das seguintes publicações:

Bruno Pimentel, Joel Arrais, “Implementação de Algoritmo de Compressão

e Descompressão de Dados para Modelo de Co-processamento

baseado em FPGA’s”, Electrónica e Telecomunicações, Jan., 2004;

Bruno Pimentel, Joel Arrais, “Desenvolvimento de Sistemas

Reconfiguráveis utilizando Handel-C”, palestra realizada no Instituto

de Engenharia Electrónica e Telemática de Aveiro (IEETA), no dia 23

de Abril de 2004;

Valery Sklyarov, Iouliia Skliarova, Bruno Pimentel, Joel Arrais,

“Hardware/Software Implementation of FPGA-targeted Matrix-

Oriented SAT Solvers”, apresentada em “The International

Conference on Field-Programmable Logic”, 2004.