Modelos de Software / Hardware Reutilizáveis para...
Transcript of Modelos de Software / Hardware Reutilizáveis para...
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.