vectores de fortran em c - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em...

90
Vectores de Fortran em C Jo˜ ao Carlos Murtinheira Dissertac ¸˜ ao para obtenc ¸˜ ao do Grau de Mestre em Engenharia Inform ´ atica e de Computadores Orientador: Prof. Pedro Manuel Guerra e Silva Reis dos Santos uri Presidente: Prof. Daniel Jorge Viegas Gonc ¸alves Orientador: Prof. Pedro Manuel Guerra e Silva Reis dos Santos Vogal: Prof. David Manuel Martins de Matos Outubro 2015

Upload: others

Post on 22-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Vectores de Fortran em C

Joao Carlos Murtinheira

Dissertacao para obtencao do Grau de Mestre em

Engenharia Informatica e de Computadores

Orientador: Prof. Pedro Manuel Guerra e Silva Reis dos Santos

Juri

Presidente: Prof. Daniel Jorge Viegas GoncalvesOrientador: Prof. Pedro Manuel Guerra e Silva Reis dos Santos

Vogal: Prof. David Manuel Martins de Matos

Outubro 2015

Page 2: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´
Page 3: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Agradecimentos

Em primeiro lugar, expresso a minha profunda e sincera gratidao ao meu professor orientador de

dissertacao, Prof. Pedro Reis Santos, cuja dedicacao foi indispensavel para levar a cabo este pro-

jecto. Agradeco por toda a disponibilidade, empenho, paciencia e enorme conhecimento sobre o tema,

factores sem os quais a redaccao desta dissertacao nao seria possıvel.

Agradeco tambem a todos os colegas e amigos que, de uma forma ou de outra, me deram o enco-

rajamento e apoio de que precisei para levar a cabo este trabalho: Alberto Carvalho, Beatriz Morgado,

Bernardo Santos, Claudia Grilo, Eduardo Martins, Mafalda Cardeira, Margarida Alberto, Miguel Coe-

lho, Nuno Duarte, Joao Neves, Jorge Pereira, Jose Cavalheiro, Rita Domingos, Soraia Alarcao e Vania

Mendonca. Em especial, quero agradecer aos meus abnegados “mentores”, Bernardo Santos, Jorge

Pereira, Mafalda Cardeira, Soraia Alarcao e Vania Mendonca, por essencialmente me ensinarem a

redigir uma dissertacao de mestrado a luz das suas proprias experiencias.

Muito obrigado a minha companheira assıdua de noitadas, Rita Domingos, pela compreensao, pe-

las gargalhadas, por toda a motivacao para seguir em frente, e acima de tudo, pela oportunidade de

partilhar a minha experiencia com alguem que, em troca, partilhou a sua.

Ao meu grande amigo Miguel Coelho, alem da disponibilizacao de hardware que tornou possıvel a

avaliacao do trabalho, quero agradecer pela enorme cumplicidade e amizade, que me mantiveram de

pe ao longo do ultimo ano.

Obrigado ainda ao insubstituıvel Jorge Pereira, que apesar da distancia fısica, conseguiu estar sem-

pre presente para me dar as palavras de animo e forca quando precisei delas. Muito obrigado pela

eterna amizade.

Finalmente, aos meus pais e familiares que sempre me apoiaram nas mais diversas vertentes, quero

agradecer por tornarem possıvel nao so este projecto, como tambem toda a minha formacao ate hoje.

Page 4: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´
Page 5: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Abstract

The programming languages C and Fortran allow the use of arrays as a way to organize sets of same-

type entities in memory. Although their purpose and functionality are similar, each language uses a

different method of addressing values stored in an array, since each one possesses a distinct strategy

of organizing the memory allocated for these structures. Depending on the conditions under which a

program is run, such as Central Processing Unit (CPU) architecture, each different strategy may cause

different performance degrees when running a program containing array operations. This project con-

sisted in combining both memory organization and access strategies into an extended version of the

C programming language. The advantages and disadvantages of using each strategy are also explo-

red, based on experimental performance measurements of several implemented algorithms running on

different CPU architectures.

Keywords

Array, C Language, Compiler, Fortran Language, Memory, Performance.

iii

Page 6: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´
Page 7: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Resumo

As linguagens de programacao C e Fortran permitem a utilizacao de vectores como forma de orga-

nizar em memoria conjuntos de entidades do mesmo tipo. Ainda que com objectivo e funcionalidade

semelhante, cada linguagem utiliza um metodo diferente de carregamento dos valores guardados em

vectores, pois cada uma possui uma estrategia propria de organizacao da memoria reservada para

estas estruturas. Dependendo das condicoes de execucao de um programa, como a arquitectura do

processador utilizado, cada estrategia podera originar diferentes nıveis de desempenho de um pro-

grama que faca uso de vectores. Neste projecto, desenvolveu-se uma forma de combinar ambas as

estrategias de organizacao e acesso a memoria numa versao estendida da linguagem C. Exploram-se

tambem as vantagens e desvantagens do uso de cada estrategia, com base em medicoes experimen-

tais do desempenho de varios algoritmos implementados e executados sobre diferentes arquitecturas

de processador.

Palavras Chave

Compilador, Desempenho, Linguagem C, Linguagem Fortran, Memoria, Vector.

v

Page 8: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´
Page 9: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Conteudo

1 Introducao 1

1.1 Motivacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.3 Estrutura do Documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Enquadramento 7

2.1 Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.2 Ponteiros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.3 Linguagem C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.4 Linguagem Fortran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.5 Linguagens MATLAB e GNU Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.6 Compiladores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.6.1 Analise Lexical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.6.2 Analise Sintactica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.6.3 Analise Semantica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.6.4 Geracao de Codigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.7 Analise Comparativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.8 Sumario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3 Solucao Proposta 17

3.1 Visao Global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.2 Descricao da Arquitectura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.2.1 Extensoes Sintacticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3.2.2 Verificacoes Semanticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3.2.3 Geracao de Codigo C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.2.4 Exemplos de Utilizacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

3.3 Metodologia de Avaliacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.4 Sumario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

vii

Page 10: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

4 Realizacao 31

4.1 Funcionalidade da Solucao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

4.2 Flex: Fast Lexical Analyzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.3 GNU Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.4 Descricao Gramatical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

4.5 Semantica e Geracao de Codigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4.6 Processo de Desenvolvimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.6.1 Tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.6.2 Identificadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

4.6.3 Comentarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

4.6.4 Declaracoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

4.6.5 Indexacoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.6.6 Funcoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.7 Problemas Enfrentados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

5 Avaliacao da Solucao 47

5.1 Modelos de Teste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

5.1.1 Soma de Vectores Tridimensionais . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

5.1.2 Produto de Matrizes Quadradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

5.1.3 Determinante: Formula de Leibniz . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

5.2 Discussao dos Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6 Conclusao 55

6.1 Conclusoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.2 Limitacoes e Trabalho Futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

A Codigo de Avaliacao 61

A.1 Soma de Vectores Tridimensionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

A.2 Produto de Matrizes Quadradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

A.3 Determinante: Formula de Leibniz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

B Tempos de Execucao 67

viii

Page 11: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Lista de Figuras

2.1 Vector bidimensional em C: Ponteiros para outros vectores. . . . . . . . . . . . . . . . . . 11

2.2 Vector bidimensional em Fortran: Bloco contıguo em memoria. . . . . . . . . . . . . . . . 12

2.3 Componentes de um compilador tıpico e fases da compilacao. . . . . . . . . . . . . . . . 13

3.1 Visao Global da solucao. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

ix

Page 12: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

x

Page 13: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Lista de Tabelas

5.1 Desempenho da soma de vectores num processador Intel x86-64 a 1.80 GHz. . . . . . . 50

5.2 Desempenho da soma de vectores num processador Intel x86-64 a 2.00 GHz. . . . . . . 50

5.3 Desempenho da soma de vectores num processador ARMv6 a 700 MHz. . . . . . . . . . 51

5.4 Desempenho do produto de matrizes num processador Intel x86-64 a 1.80 GHz. . . . . . 51

5.5 Desempenho do produto de matrizes num processador Intel x86-64 a 2.00 GHz. . . . . . 52

5.6 Desempenho do produto de matrizes num processador ARMv6 a 700 MHz. . . . . . . . . 52

5.7 Desempenho da formula de Leibniz num processador Intel x86-64 a 1.80 GHz. . . . . . . 53

5.8 Desempenho da formula de Leibniz num processador Intel x86-64 a 2.00 GHz. . . . . . . 53

5.9 Desempenho da formula de Leibniz num processador ARMv6 a 700 MHz. . . . . . . . . . 54

B.1 Execucao da soma de vectores num processador Intel x86-64 a 1.80 GHz. . . . . . . . . 68

B.2 Execucao da soma de vectores num processador Intel x86-64 a 2.00 GHz. . . . . . . . . 68

B.3 Execucao da soma de vectores num processador ARMv6 a 700 MHz. . . . . . . . . . . . 68

B.4 Execucao do produto de matrizes num processador Intel x86-64 a 1.80 GHz. . . . . . . . 69

B.5 Execucao do produto de matrizes num processador Intel x86-64 a 2.00 GHz. . . . . . . . 69

B.6 Execucao do produto de matrizes num processador ARMv6 a 700 MHz. . . . . . . . . . . 69

B.7 Execucao da formula de Leibniz num processador Intel x86-64 a 1.80 GHz. . . . . . . . . 70

B.8 Execucao da formula de Leibniz num processador Intel x86-64 a 2.00 GHz. . . . . . . . . 70

B.9 Execucao da formula de Leibniz num processador ARMv6 a 700 MHz. . . . . . . . . . . . 70

xi

Page 14: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

xii

Page 15: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Lista de Algoritmos

4.1 Geracao de codigo de uma declaracao. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4.2 Geracao de codigo de uma indexacao. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

xiii

Page 16: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

xiv

Page 17: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Listagens

3.1 Somatorio dos valores de uma matriz (linguagem C tradicional). . . . . . . . . . . . . . . 20

3.2 Somatorio dos valores de uma matriz (linguagem C estendida). . . . . . . . . . . . . . . . 20

3.3 Soma dos elementos de duas matrizes (linguagem C estendida). . . . . . . . . . . . . . . 24

3.4 Soma dos elementos de duas matrizes (linguagem C tradicional). . . . . . . . . . . . . . 25

3.5 Alteracao do tipo do vector retornado pela funcao de reserva. . . . . . . . . . . . . . . . . 26

3.6 Acessos a vectores de ambos os tipos (linguagem C). . . . . . . . . . . . . . . . . . . . . 27

3.7 Acessos a vectores de ambos os tipos (linguagem assembly). . . . . . . . . . . . . . . . 28

3.8 Carregamento de um valor num vector com 6 dimensoes. . . . . . . . . . . . . . . . . . . 29

4.1 Exemplo de entrada do compilador. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

4.2 Exemplo de saıda do compilador. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

A.1 Soma de dois vectores tridimensionais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

A.2 Produto de duas matrizes quadradas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

A.3 Formula de Leibniz para o determinante de uma matriz. . . . . . . . . . . . . . . . . . . . 65

xv

Page 18: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

xvi

Page 19: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Acronimos

ARM Acorn RISC Machine

CPU Central Processing Unit

GCC GNU Compiler Collection

GPL GNU General Public License

LALR Look-Ahead Left-to-Right

xvii

Page 20: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

xviii

Page 21: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

1Introducao

Conteudo

1.1 Motivacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.3 Estrutura do Documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1

Page 22: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

2

Page 23: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

A linguagem C, originaria de cerca de 1972 [1], surgiu com o intuito de fornecer ao programador um

elevado nıvel de controlo sobre a quantidade de memoria utilizada, e sobre a forma como a mesma se

organiza no espaco de enderecamento de um programa [2]. Por este motivo, esta e uma linguagem

indicada ao desenvolvimento de programas que tenham fortes requisitos de gestao dos recursos de

memoria utilizados [1].

Desde a sua origem, a linguagem C continua a ser utilizada como standard no desenvolvimento de

aplicacoes informaticas, e principalmente de sistemas operativos [3], mantendo a especificacao original

da autoria de Brian Kernighan e Dennis Ritchie [2], no que toca ao funcionamento das operacoes de

reserva e acesso a memoria.

A linguagem Fortran, mais antiga (meados da decada de 50), teve como objectivo maximizar o

desempenho da realizacao de operacoes vectoriais, divergindo da linguagem C em relacao ao controlo

sobre a memoria reservada que e fornecido ao programador [4], bem como no que diz respeito ao modo

como as operacoes de acesso sao realizadas [5,6].

1.1 Motivacao

Este projecto pretende abordar, como se descreve em maior detalhe no Capıtulo 2, a necessidade

de combinar pelo menos duas linguagens de programacao, neste caso C e Fortran, quando se pre-

tende operar de modos distintos sobre a memoria reservada para os vectores multidimensionais de um

programa [2,6].

Por outro lado, se o programador pretender utilizar apenas uma unica linguagem, ve-se obrigado

a optar por uma mais flexıvel no que toca a organizacao da memoria dos vectores no seu espaco de

enderecamento, mas que se pode revelar menos eficiente no acesso ao seu conteudo, como e o caso

da linguagem C, por oposicao a uma linguagem mais restritiva, mas que podera ser mais eficiente nos

acessos, como a linguagem Fortran [4,7].

Com este trabalho, pretendeu-se concretizar uma solucao para este problema, de modo a permi-

tir ao programador o uso de vectores multidimensionais na linguagem C, com operacoes de acesso

potencialmente mais eficientes do que aquelas que a linguagem fornece, e que estao presentes na

linguagem Fortran [4].

O trabalho teve como principal motivacao a extraccao de conclusoes sobre o desempenho compa-

rativo de cada tipo de vectores, avaliando cada um em diferentes condicoes, como se descreve mais

adiante.

3

Page 24: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

1.2 Objectivos

Para solucionar o problema referido na seccao anterior, propos-se desenvolver uma versao mo-

dificada da linguagem C, estendendo-a de modo a acrescentar um tipo novo de vectores, os quais

funcionam de modo identico aos da linguagem Fortran. Pretendeu-se tambem que as operacoes com

vectores da linguagem C tradicional fossem inteiramente preservadas, de modo a permitir a utilizacao

de ambos os tipos de vectores num so programa, implementado numa unica linguagem.

Este tipo de abordagem, utilizada em projectos de diferentes naturezas e finalidades [8, 9], permite

que qualquer programa desenvolvido segundo a especificacao tradicional da linguagem C seja inteira-

mente compatıvel com a versao modificada [9], uma vez que apenas consiste em acrescentar regras

sintacticas e correspondentes verificacoes semanticas [10,11] a especificacao existente, sem a alterar

de qualquer outro modo.

De modo a concretizar a solucao proposta, este trabalho teve como objectivo o desenvolvimento de

um compilador, ou seja, um programa de traducao de codigo [10]. Este compilador recebe, como en-

trada, programas escritos na versao modificada da linguagem C, produzindo programas equivalentes,

escritos na linguagem C tradicional. A saıda desta ferramenta pode entao ser processada por compi-

ladores da linguagem C ja existentes, de modo a que possam ser aproveitadas as optimizacoes neles

incluıdas como consequencia do seu proprio desenvolvimento [8].

1.3 Estrutura do Documento

No presente documento descrevem-se, em primeiro lugar, os conceitos que contextualizam o pro-

blema a solucionar. Esta informacao encontra-se no Capıtulo 2, no qual se define o conceito de vector,

ou array, no ambito de uma linguagem de programacao, explicando qual o seu proposito, bem como

o modo de utilizacao e funcionamento destas estruturas nas linguagens de programacao envolvidas

na solucao desenvolvida: a linguagem C e a linguagem Fortran. Referem-se ainda breves exemplos

de outras linguagens, devido a relacao que apresentam com estas, ou as particularidades que as tor-

nam relevantes para o contexto deste trabalho. Finalmente, descreve-se o processo de compilacao

do codigo de um programa, detalhando todas as fases que o constituem e os componentes que um

compilador (ou tradutor) deve possuir para as realizar.

No Capıtulo 3 sao descritos os componentes arquitecturais da solucao. Visto tratar-se de uma

extensao de uma linguagem de programacao, este capıtulo descreve os mecanismos de analise lexical,

sintactica e semantica, referindo quais as regras a acrescentar a gramatica da linguagem existente, e

qual o codigo a gerar para as mesmas. E tambem neste capıtulo que se descreve em pormenor qual o

mecanismo de funcionamento dos vectores que se procurou implementar. Por fim, fornecem-se alguns

exemplos de correcta utilizacao da linguagem estendida.

4

Page 25: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

O Capıtulo 4 descreve a implementacao do trabalho no que diz respeito a programacao realizada

e as ferramentas utilizadas para o desenvolvimento do compilador que constitui a solucao. E comple-

mentada com os algoritmos de maior relevancia, com vista a melhor documentar o trabalho realizado.

O Capıtulo 5 avalia a solucao desenvolvida, atraves de medicoes e tratamento estatıstico do tempo

de execucao de programas elaborados com recurso a extensao da linguagem, por oposicao a progra-

mas equivalentes, sem recurso a mesma. No final deste capıtulo, sera possıvel concluir acerca das

vantagens e desvantagens do uso da extensao da linguagem, avaliando a solucao produzida na sua

totalidade.

Por ultimo, o Capıtulo 6 apresenta em resumo o conteudo do documento, referindo os aspectos

principais de cada capıtulo, e aludindo as limitacoes e possibilidades de melhoria do trabalho desenvol-

vido.

5

Page 26: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

6

Page 27: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

2Enquadramento

Conteudo

2.1 Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.2 Ponteiros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.3 Linguagem C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.4 Linguagem Fortran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.5 Linguagens MATLAB e GNU Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.6 Compiladores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.7 Analise Comparativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.8 Sumario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

7

Page 28: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

8

Page 29: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Neste capıtulo exploram-se os conceitos fundamentais ao entendimento do projecto desenvolvido,

bem como os aspectos mais relevantes das linguagens de programacao envolvidas no contexto deste

projecto. Concretamente, sao referidas as vantagens e desvantagens da utilizacao de cada linguagem,

os conceitos de programacao relacionados com o tema, e ainda a constituicao tıpica de uma ferramenta

de compilacao.

2.1 Vectores

Em programacao, o conceito de vector (ou array ) e tipicamente definido como um conjunto de

multiplos valores do mesmo tipo guardados contiguamente no espaco de enderecamento de um pro-

grama [2,6,12]. O acesso a cada elemento do vector e realizado atraves de uma operacao de indexacao,

a qual consiste na soma aritmetica de um valor de deslocamento ao endereco de memoria da posicao

inicial do vector [2, 4, 6]. Para facilitar a programacao, um vector pode ter um numero de dimensoes

superior a 1, o que faz com que seja necessario realizar tambem a indexacao em cada uma dessas

dimensoes [2,6].

A tıtulo de exemplo, considere-se a implementacao de um progama de desenho, em que o utilizador

dispoe de uma tela rectangular e faz uso da interface grafica para alterar a cor de cada ponto individual

da tela. Neste contexto, o programador pode optar por organizar esses pontos como uma matriz de

duas dimensoes, ficando cada uma associada a um eixo coordenado da tela. Desta forma, cada ponto

e acedido e modificado pelo programa atraves do fornecimento de um par de coordenadas (x, y), pro-

venientes da interface de utilizador, o que corresponde a obter o endereco do elemento do vector de

pontos correspondente, atraves da indexacao do vector com esses mesmos valores x e y.

Apesar desta definicao generica do conceito de vector, cada linguagem de programacao pode es-

pecifica-la de formas distintas [2, 4], factor do qual dependera a eficiencia dos programas que os seus

compiladores produzem, como se descreve nas seccoes seguintes deste capıtulo.

2.2 Ponteiros

O conceito de ponteiro e normalmente definido como uma entidade que guarda o valor de um

endereco de memoria com algum significado relevante para o programa [1, 2, 12]. Apesar de poder

nao ter um valor valido definido, um ponteiro esta normalmente associado a uma variavel no espaco

de enderecamento, indicando o endereco de memoria que a mesma ocupa, sendo tambem frequente

a sua utilizacao na linguagem C, para indicar o endereco da posicao inicial de um vector [2].

Na linguagem Fortran, um ponteiro nao pode ser utilizado para obter directamente o endereco da

entidade a qual esta associado; apenas permite aceder ao valor guardado nesse endereco, entre outras

9

Page 30: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

particularidades [4, 6]. Na linguagem C, por oposicao, um ponteiro nao e mais do que um valor do tipo

inteiro sem sinal, que contem o valor do endereco para o qual aponta [1]. Esta simplicidade permite

ao programador realizar operacoes aritmeticas (como somas ou subtraccoes) envolvendo ponteiros e

ındices de deslocamento. Destas operacoes resultam novos enderecos de memoria, os quais podem

ser usados para aceder aos valores guardados nesses enderecos, desde que nao seja transposto o

espaco de enderecamento do programa [1,2,4].

As operacoes de aritmetica de ponteiros sao uteis no processamento de vectores na linguagem

C, pois estas estruturas sao constituıdas por blocos de memoria contıgua que armazenam multiplos

valores [1,2], como se descreve na proxima seccao.

2.3 Linguagem C

A linguagem C proporciona ao programador um grande nıvel de controlo sobre a organizacao das

estruturas de dados de um programa no seu espaco de enderecamento [1], bem como o acesso as

mesmas.

Esta linguagem fornece tres tipos de vectores, cuja especificacao difere, dependendo do modo como

e realizada a reserva de memoria, apesar de serem semelhantes em termos de utilizacao. Os vectores

obtidos atraves de reserva estatica de memoria sao blocos contıguos com tamanho fixo, igual ao pro-

duto do numero de bytes de cada elemento do vector pelos valores especificados na sua declaracao.

Para obter um vector deste tipo, o programador precisa apenas de declara-lo, especificando os tama-

nhos das suas dimensoes atraves de expressoes numericas constantes [2].

Os vectores obtidos atraves de reserva local (com recurso a funcao alloca, definida na biblioteca

padrao da linguagem) sao semelhantes aos vectores estaticos, pois nao e possıvel alterar o seu ta-

manho. No entanto, permitem fazer uso de valores guardados em variaveis para especifica-lo, e nao

apenas expressoes constantes [1]. O valor retornado por esta funcao e um ponteiro para um bloco de

memoria contıguo, com tamanho igual ao numero de bytes passado como argumento.

A reserva dinamica de memoria, por outro lado, tambem realizada com recurso a funcoes da biblio-

teca padrao da linguagem C (stdlib), torna possıvel alterar o tamanho do vector resultante, o que nao

e permitido com reserva estatica ou reserva local [1,2].

Independentemente do tipo de reserva, a operacao de indexacao de vectores na linguagem C con-

siste, numa primeira fase, em obter o endereco guardado no ponteiro resultante da operacao de reserva,

o qual e utilizado para calcular o endereco pretendido, atraves da soma do deslocamento correspon-

dente. So apos este calculo e possıvel realizar o acesso ao valor pretendido [1,2].

Para possibilitar o uso de vectores com mais do que uma dimensao, e necessario elaborar uma hi-

erarquia de vectores de ponteiros, cada um dos quais pode ter tamanho variavel, com tantos nıveis

10

Page 31: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

hierarquicos quanto o numero de dimensoes pretendidas para o vector [2]. A Figura 2.1 ilustra a

organizacao em memoria deste tipo de vectores. Na reserva dinamica, este e um processo mais com-

plexo para o programador, pois envolve sucessivas reservas de memoria, de modo a preencher devi-

damente todos os nıveis da hierarquia com vectores de ponteiros para os nıveis inferiores. A operacao

de indexacao multidimensional envolve tambem tantas sequencias de calculos de deslocamentos e

carregamentos de valores quanto o numero de dimensoes do vector [2].

Figura 2.1: Vector bidimensional em C: Ponteiros para outros vectores.

A reserva dinamica de memoria introduz ainda a ocorrencia de fragmentacao espacial dos blocos

obtidos, no que diz respeito a organizacao dos vectores [1].

A tıtulo de exemplo, a obtencao de um vector dinamico de duas dimensoes, ou seja, uma matriz

de X linhas por Y colunas, exige que seja invocada a funcao de reserva de memoria para obter,

numa primeira fase, um ponteiro para um vector de outros ponteiros, os quais resultarao, em fases de

execucao posteriores, de Y chamadas subsequentes a mesma funcao1. Este processo, por um lado,

permite poupar memoria, pois cada vector e obtido individualmente e pode ter uma dimensao diferente

dos restantes. Origina, no entanto, uma inevitavel dispersao dos varios vectores, podendo cada um ficar

separado dos restantes por grandes intervalos de memoria, devido ao mecanismo de aleatoriedade do

espaco de enderecamento, presente em muitos sistemas operativos. A isto acrescenta-se a ocorrencia

de fragmentacao externa [1], provocada pela libertacao da memoria destes vectores. Neste caso,

surgem diversos lotes de memoria livre, os quais podem nunca ser reaproveitados, caso o seu tamanho

seja demasiado pequeno. Trata-se, portanto, de um compromisso entre a flexibilidade das operacoes

de reserva de memoria da linguagem e a eficiencia do acesso a mesma.

1Neste exemplo, considera-se que o algoritmo exige a reserva de uma coluna por cada ındice das linhas da matriz

11

Page 32: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

2.4 Linguagem Fortran

Surgida na decada de 50, e mais antiga do que a linguagem C, a linguagem Fortran2 apresentava,

ja desde as suas especificacoes iniciais, uma forma eficiente de programacao e calculo de operacoes

aritmeticas com vectores de multiplas dimensoes [5]. Esta propriedade da linguagem prende-se com o

facto de ter sido criada com o objectivo de facilitar a introducao de formulas matematicas e o processa-

mento intensivo de calculos numericos necessario em areas como a Fısica, a Quımica ou a Engenharia.

Ainda assim, no que diz respeito a constituicao dos vectores em memoria, bem como a capacidade

de manipulacao da mesma pelo programador, trata-se de uma linguagem mais restritiva do que a lin-

guagem C. De facto, contrariamente a esta, um elemento de um vector na linguagem Fortran e sempre

acedido atraves de um deslocamento aplicado ao ponteiro para a sua posicao inicial, independente-

mente do numero de dimensoes que possa ter [4–6]. Este deslocamento e entao utlizado para aceder

directamente a posicao desejada, realizando-se apenas uma unica operacao de carregamento para o

efeito [4].

Consequentemente, como ilustrado na Figura 2.2, um vector multidimensional em Fortran esta sem-

pre restrito a condicao de contiguidade em memoria dos seus elementos, e consequentemente, nao e

permitida a diferenca de tamanho entre vectores parciais do mesmo nıvel hierarquico, contrariamente a

linguagem C.

Figura 2.2: Vector bidimensional em Fortran: Bloco contıguo em memoria.

Exemplificando, para obter o elemento contido na posicao (i, j, k) de um vector tridimensional com

ındices variando entre (0, 0, 0) e (x, y, z), o deslocamento a somar a primeira posicao em memoria do

mesmo e dado, de forma imediata, por [4]:

δ = i+ jx+ kxy

Desta forma, em comparacao com a linguagem C, e apesar das restricoes na organizacao dos vec-

tores em memoria, a linguagem Fortran podera ser mais eficiente no acesso a mesma, especialmente

para vectores com numeros elevados de dimensoes.

2O nome Fortran e um acronimo que significa FORmula TRANslation.

12

Page 33: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

2.5 Linguagens MATLAB e GNU Octave

Dado o enfase em calculo matricial da linguagem MATLAB, nao e de estranhar que a sua compo-

nente vectorial seja maioritariamente desenvolvida em Fortran. De facto, caso o programador o deseje,

pode aceder e interagir com rotinas de Fortran durante execucao dos seus programas em MATLAB, ou

inversamente, invocar funcoes de MATLAB em programas na linguagem Fortran [13]. A literatura revela

tambem que e possıvel o desenvolvimento de ferramentas de traducao de codigo MATLAB para codigo

Fortran [14].

Ainda assim, visto ser uma linguagem interpretada de alto nıvel, constituıda segundo uma arquitec-

tura em camadas implementadas em linguagens diferentes3, e devido ao elevado numero de reservas

de memoria que um programa em MATLAB necessita frequentemente de realizar, acaba por se sacrifi-

car consideravelmente o desempenho desta linguagem [14].

Outras linguagens semelhantes seguem o mesmo tipo de abordagem, como a linguagem GNU

Octave, cujo objectivo e ser tao compatıvel com a linguagem MATLAB quanto possıvel, pelo que faz

uso das mesmas linguagens e possibilita tambem a interaccao com programas externos [15,16]. Possui,

portanto, as mesmas desvantagens de desempenho referidas.

2.6 Compiladores

Como ja foi referido, pretendeu-se estender a especificacao da linguagem C existente, pelo que

foi necessario desenvolver um compilador que processe codigo escrito na versao modificada da lin-

guagem, traduzindo esse codigo para uma versao intermedia, sob a forma de codigo C tradicional, de

modo a que, no final de todo o processo de compilacao, seja possıvel obter o codigo-maquina cor-

respondente [10], ou seja, o codigo binario que e efectivamente reconhecido e processado por uma

CPU. Nesta seccao, descrevem-se os principais componentes do pipeline que constitui um compilador

tradicional, os quais se ilustram na Figura 2.3.

Figura 2.3: Componentes de um compilador tıpico e fases da compilacao.

3Alem das rotinas de Fortran, a interface grafica de utilizador e desenvolvida em Java, sendo a sua camada principal imple-mentada em C++.

13

Page 34: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

2.6.1 Analise Lexical

A primeira fase do processo de compilacao consiste na analise lexical do ficheiro de codigo fonte,

que e a entrada do compilador. Esta analise reconhece os elementos da linguagem (ou tokens) pre-

sentes no codigo [10,11], identificando univocamente cada um, bem como a posicao no codigo de cada

elemento relativamente aos restantes. Esta informacao e passada para o nıvel seguinte do compilador,

o analisador sintactico. Caso sejam detectados no codigo elementos lexicais que nao pertencam a

linguagem, devera ser assinalado um erro pelo compilador [10].

Dependendo da especificacao da linguagem, pode tambem nesta fase ser realizado algum proces-

samento previo, como reconhecimento de tipos de literais ou eliminacao de comentarios [11].

2.6.2 Analise Sintactica

A segunda fase da compilacao consiste na construcao de uma arvore sintactica, de acordo com a

ordem pela qual sao identificados os tokens ao nıvel do analisador lexical [10,11]. Esta arvore e cons-

truıda segundo as regras gramaticais da linguagem, as quais indicam qual a combinacao de elementos

da linguagem que constitui cada operacao. Deste modo, as operacoes estruturalmente mais complexas

sao colocadas em nıveis superiores da arvore, tendo como nos filhos as operacoes mais simples que

as constituem. Adicionalmente, cada literal deve ficar associado ao seu valor, na base da arvore, de

modo a que possa ser processado directamente pelo analisador semantico, que desempenha a fase

seguinte da compilacao [10].

E ainda na fase de analise sintactica que o compilador deve realizar e reportar a deteccao de erros

sintacticos presentes no codigo. Estes sao erros que ocorrem quando o programador desrespeita as

regras gramaticais da linguagem, ao escrever combinacoes de elementos lexicais que nao possuam

uma estrutura sintactica correspondente na gramatica da linguagem [10].

2.6.3 Analise Semantica

Esta fase da compilacao tem como entrada a arvore sintactica gerada na fase anterior, e consiste

em percorrer e aumentar a mesma, visitando todos os seus nos e propagando os valores de cada no

inferior, comecando nas folhas, para os nos superiores, de acordo com a operacao associada a cada

um, ate ser atingida a raiz da arvore. Durante a analise semantica, o compilador devera reportar erros

de semantica presentes no codigo do programa, ou seja, combinacoes de nos da arvore sintactica que

contenham significados ou valores incompatıveis entre si [10].

E tambem nesta fase que e verificada a validade de atribuicoes, correspondencias entre nomes de

variaveis ou funcoes e as suas definicoes, bem como correspondencias de tipos (type checking) [10].

14

Page 35: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

2.6.4 Geracao de Codigo

A ultima fase da compilacao consiste na seleccao de instrucoes correspondentes aos nos da arvore

semantica proveniente da fase anterior, compreendendo tambem a reserva de registos e a optimizacao

do codigo resultante. Cada no da arvore equivale a um conjunto de instrucoes na linguagem de saıda

do compilador4. Deste modo, o produto final da compilacao e obtido atraves da combinacao das varias

instrucoes que constituem, na linguagem pretendida, o programa equivalente a sequencia de entrada

do compilador [10].

2.7 Analise Comparativa

No que diz respeito a flexibilidade de gestao da memoria dos vectores que a linguagem C fornece

ao programador, esta permite optimizar a quantidade de memoria reservada em cada momento de

execucao, o que por sua vez podera permitir minimizar os requisitos de hardware sobre o qual o pro-

grama executa. Porem, tem como consequencia uma menor eficiencia no acesso a memoria em vec-

tores multidimensionais, quando estes sao organizados como uma hierarquia de vectores de ponteiros.

A causa desta ineficiencia prende-se com a quantidade de operacoes de carregamento de enderecos

que este tipo de organizacao implica realizar quando se pretende aceder a um dado valor.

De facto, para carregar um valor guardado num vector de n dimensoes organizado desta forma, o

processador necessita de realizar n− 1 carregamentos adicionais, de modo a obter primeiro o valor de

cada ponteiro em cada nıvel da hierarquia, e so depois o valor efectivamente pretendido.

Na linguagem Fortran, por outro lado, visto que a indexacao de um vector consiste sempre na soma

aritmetica de um deslocamento ao endereco da sua posicao inicial, como se ilustrou na Seccao 2.4,

apenas e necessario efectuar o calculo desse deslocamento, obtendo-se o valor pretendido atraves de

um unico carregamento.

E de notar, no entanto, que o referido calculo consiste, em parte, na realizacao de multiplicacoes dos

ındices que o programador indica, as quais sao tao mais numerosas quanto o numero de dimensoes do

vector. Por este motivo, no caso particular de CPUs que nao fornecam a operacao de multiplicacao ao

nıvel de hardware, como a maioria dos actuais processadores Acorn RISC Machine (ARM), e introdu-

zido um custo computacional significativo para numeros elevados de dimensoes, devido a necessidade

de realizar as multiplicacoes ao nıvel do software. Esta desvantagem pode nao justificar a optimizacao

da linguagem Fortran face aos multiplos carregamentos da linguagem C neste tipo de arquitectura.

Ainda assim, dependendo do codigo fonte a compilar, podera ser possıvel a substituicao das opera-

coes de multiplicacao por operacoes de deslocamento a esquerda e de soma5, dada a equivalencia

4Exemplos comuns sao linguagens assembly ou codigo binario.5Optimizacao conhecida como strength reduction, pois consiste em substituir operacoes computacionalmente pesadas (ditas

“fortes”) por operacoes mais leves (ou “fracas”).

15

Page 36: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

existente entre uma multiplicacao por uma potencia de 2 e um deslocamento a esquerda dos bits

de um registo. Nos casos em que esta optimizacao e possıvel, podera, mesmo numa arquitectura

ARM, ter menor custo computacional o uso dos vectores da linguagem Fortran, em comparacao aos da

linguagem C.

2.8 Sumario

A reserva de memoria na linguagem C permite uma grande flexibilidade na organizacao da mesma,

sendo possıvel minimizar a quantidade de memoria reservada. No entanto, as operacoes de indexacao

de vectores exigem sucessivas computacoes de calculo de deslocamentos e obtencao de valores ate

se obter efectivamente o valor pretendido.

A linguagem Fortran nao permite tanta flexibilidade, mas tem como vantagem a linearidade em

memoria dos vectores multidimensionais, o que permite aceder directamente aos seus elementos com

a simples aplicacao de um deslocamento ao ponteiro para a posicao inicial do vector.

A linguagem MATLAB, entre outras, faz uso desta propriedade da linguagem Fortran para optimizar

os tempos de execucao dos seus programas. No entanto, visto que os componentes do ambiente

MATLAB sao implementados em linguagens diferentes, que necessitam de comunicar constantemente

entre si, a sua eficiencia fica prejudicada.

16

Page 37: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

3Solucao Proposta

Conteudo

3.1 Visao Global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.2 Descricao da Arquitectura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.3 Metodologia de Avaliacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.4 Sumario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

17

Page 38: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

18

Page 39: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Neste capıtulo e descrita a abordagem seguida para a implementacao da solucao realizada. Em

primeiro lugar, descreve-se a extensao da linguagem desenvolvida com uma perspectiva global. Segui-

damente, descreve-se a arquitectura da solucao, a qual e complementada com exemplos de utilizacao

dos novos vectores, bem como de codigo gerado em diferentes fases do processo de compilacao.

3.1 Visao Global

Como ja foi referido, no decurso deste trabalho, concretizou-se uma extensao da linguagem C, re-

plicando o modo como a memoria e organizada em vectores da linguagem Fortran. Para o efeito,

desenvolveu-se um compilador que processa codigo escrito na versao estendida da linguagem, produ-

zindo codigo na linguagem C tradicional. Este pode, por sua vez, ser processado por um compilador ja

existente dessa mesma linguagem.

Figura 3.1: Visao Global da solucao.

O desenvolvimento de um compilador implicou a implementacao das fases do processo de compila-

cao, como descrito no capıtulo anterior. Para a implementacao desta extensao, optou-se por nao definir

novos elementos da linguagem (tokens), pois os que ja existem sao suficientes para distinguir os novos

vectores dos tradicionais. Para tal, apenas e necessaria a utilizacao de combinacoes diferentes dos

mesmos. Deste modo, a fase de analise lexical da compilacao nao exigiu uma quantidade significativa

trabalho de programacao, tendo a maior parte do esforco sido dedicada as fases posteriores.

O analisador sintactico foi desenvolvido com recurso a ferramenta GNU Bison [11]. Esta ferramenta

permite gerar a arvore sintactica de um programa a partir da especificacao da sua gramatica formal. Foi

necessaria a criacao de regras para processar declaracoes e indexacoes (acessos) dos novos vectores,

segundo a sintaxe escolhida para os mesmos, a qual se descreve em maior detalhe na seccao seguinte.

Foram tambem acrescentadas regras para realizar a passagem destes vectores como argumentos de

funcoes.

Para exemplificar a sintaxe referida, tome-se como exemplo o problema de somar iterativamente to-

dos os elementos de um vector de inteiros bidimensional, com 20 linhas por 30 colunas. Este problema

pode ser resolvido, na linguagem C tradicional, atraves de 2 ciclos encadeados, como se exemplifica

na funcao da Listagem 3.1.

19

Page 40: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Para implementar a mesma operacao com recurso aos novos vectores, utiliza-se a sintaxe da funcao

definida na Listagem 3.2, a qual equivale a Listagem 3.1.

Listagem 3.1: Somatorio dos valores de uma matriz (linguagem C tradicional).

1 int somatorio(int v[20][30]) {

2 int i, j, val = 0;

3 for(i = 0; i < 20; ++i) {

4 for(j = 0; j < 30; ++j) {

5 val += v[i][j];

6 }

7 }

8 return val;

9 }

Listagem 3.2: Somatorio dos valores de uma matriz (linguagem C estendida).

1 int somatorio(int v[20;30]) {

2 int i, j, val = 0;

3 for(i = 0; i < 20; ++i) {

4 for(j = 0; j < 30; ++j) {

5 val += v[i;j];

6 }

7 }

8 return val;

9 }

O componente de analise semantica necessita de criar entradas na tabela de sımbolos do pro-

grama para cada vector declarado, de modo semelhante as restantes variaveis e funcoes. Por fim, o

componente gerador de codigo produz declaracoes, de modo a reservar para cada vector o numero de

bytes adequado, bem como operacoes de indexacao, entre outras. Estas sao efectuadas recorrendo

a aritmetica de ponteiros, atraves do calculo do deslocamento pretendido. Todas estas operacoes sao

descritas em maior detalhe nas proximas subseccoes.

3.2 Descricao da Arquitectura

Para o desenvolvimento do compilador, foi necessario elaborar as regras gramaticais que constituem

a analise sintactica da extensao da linguagem, definir a estrutura da tabela de sımbolos da analise

20

Page 41: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

semantica e definir tambem a seleccao de instrucoes da fase de geracao de codigo, bem como as

operacoes aritmeticas associadas a reserva de memoria e indexacao dos novos vectores, abordadas

na Subseccao 3.2.2.

3.2.1 Extensoes Sintacticas

Para os novos vectores da extensao, utiliza-se uma sintaxe semelhante a ja existente para os vec-

tores tradicionais da linguagem C. A declaracao de um vector deste tipo segue as regras gramaticais

seguintes:

D → T N [ E ; S ]

S → E ; S | E | ε

Nas regras acima, sao sımbolos terminais os parentesis rectos e o ponto e vırgula, designando as

letras maiusculas os sımbolos nao terminais. Os sımbolos T , N e E designam, respectivamente, um

tipo, um nome e uma expressao numerica constante, de acordo com a gramatica da linguagem C ja

existente. De acordo com estas regras, para o programador declarar um destes vectores, devera faze-lo

indicando os valores maximos para cada dimensao, separados por ponto e vırgula. Estas regras apenas

identificam vectores com mais do que uma dimensao, pois a extensao da linguagem desenvolvida

apenas diz respeito a esse caso.

De modo semelhante, seja N o nome do vector, presente na tabela de sımbolos do programa, e X

uma expressao numerica (constante ou nao), a operacao de indexacao, identificada por I, realiza-se

de acordo com as regras seguintes:

I → N [ X ; P ]

P → X ; P | X

Por fim, para definir uma funcao F , que receba um destes vectores como argumento, seja C um

bloco de codigo que constitui o corpo da funcao, utilizam-se as seguintes regras:

21

Page 42: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

F → T N ( A ) { C }

A → T M | T M , A | ε

M → N | N [ J ]

J → E ; K

K → J | E | ε

No calculo dos deslocamentos relativos a operacao de indexacao, optou-se por processar as di-

mensoes dos novos vectores no sentido da esquerda para a direita. Por este motivo, e permitido omitir

a ultima dimensao, como se justifica na proxima subseccao. Para as restantes operacoes da linguagem

estendida, mantem-se as propriedades da linguagem existente.

3.2.2 Verificacoes Semanticas

As regras gramaticais referidas foi necessario associar o comportamento correspondente do compi-

lador da extensao desenvolvida. A operacao de declaracao de um vector consiste em criar uma entrada

na tabela de sımbolos do compilador, associando cada nome a uma estrutura que contem o numero de

dimensoes do vector, n, e os tamanhos t1 . . . tn de cada dimensao. Deste modo, e possıvel calcular o

numero total de bytes a reservar para o vector, o qual, seja b o numero de bytes de cada elemento, e

dado por:

V = b

n∏i=1

ti (3.1)

De modo a reproduzir o comportamento das indexacoes de vectores na linguagem Fortran, descrito

na Seccao 2.4, a operacao de indexacao faz uso da referida estrutura de dados para efectuar o calculo

do endereco de memoria pretendido. Esse calculo consiste na aplicacao de um deslocamento ao

ponteiro para a posicao inicial do vector. Concretamente, para aceder a posicao [x1 . . . xn] de um vector

V com n dimensoes, de tamanhos t1 . . . tn, para n > 1, e inıcio na posicao de memoria p, sera calculado

o valor dado pela expressao:

V [x1 . . . xn] =

n∑i=1

xi i−1∏j=1

tj

b+ p (3.2)

Os vectores de dimensao 1, como ja referido, sao tratados do mesmo modo que na linguagem C

tradicional.

22

Page 43: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

3.2.3 Geracao de Codigo C

A seleccao de instrucoes da linguagem C substitui declaracoes dos novos vectores por operacoes de

reserva estatica da quantidade de memoria correspondente. O valor a reservar sera o valor calculado

para V , segundo a Expressao (3.1), referida na subseccao anterior.

A indexacao corresponde ao calculo do deslocamento ja mencionado, o qual e aplicado ao ponteiro

para a posicao inicial do vector, reproduzindo o comportamento da linguagem Fortran. Matematica-

mente, conforme a Expressao (3.2), esta operacao corresponde a soma do valor desse ponteiro ao

somatorio dos ındices de cada dimensao, multiplicando cada um, em cada iteracao do calculo do so-

matorio, pelos tamanhos de todas as dimensoes processadas nas iteracoes anteriores. Apos se obter

o endereco resultante da aplicacao do deslocamento, pode ser realizada a leitura ou escrita do valor

guardado nesse mesmo endereco.

A passagem de um vector como argumento de uma funcao implica que sejam explicitados, no codigo

da sua definicao (bem como nas ocorrencias do seu prototipo, caso existam), os valores das dimensoes

do vector, de modo a que possam ser utilizados no calculo dos deslocamentos no contexto da funcao

chamada.

Exemplifica-se, na Listagem 3.3, o codigo C gerado para as operacoes de declaracao e passagem

como argumento dos novos vectores, de acordo com a extensao desenvolvida. O exemplo define uma

funcao que realiza a soma de todos os elementos de duas matrizes de 50 linhas por 60 colunas. Apos

ser processado pelo compilador desenvolvido, o codigo resultante sera como se ilustra na Listagem 3.4.

E de notar que, com esta implementacao, se torna desnecessario especificar a ultima dimensao de

cada vector, quer na sua declaracao, quer na passagem como argumento de uma funcao, pois a mesma

nunca e utilizada no calculo dos deslocamentos. Pode observar-se que o calculo do deslocamento para

o acesso a matriz mat2, no corpo da funcao total apenas inclui o tamanho da primeira dimensao.

Por este motivo, deixa-se ao criterio do programador a omissao dessa dimensao no uso deste tipo de

vectores. (De modo semelhante, os vectores tradicionais da linguagem C tambem permitem a omissao

de uma das dimensoes.)

23

Page 44: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Listagem 3.3: Soma dos elementos de duas matrizes (linguagem C estendida).

1 #include <stdio.h>

2

3 int v[50][60];

4 int u[50;60];

5

6 int total(int mat1[50][60], int mat2[50;60]) {

7 int i, j, res = 0;

8 for(i = 0; i < 50; ++i) {

9 for(j = 0; j < 60; ++j) {

10 res += mat1[i][j] + mat2[i;j];

11 }

12 }

13 return res;

14 }

15

16 int main() {

17

18 /* Inicializacao das matrizes

19 ...

20

21 */

22

23 printf("%d\n", total(v, u));

24 return 0;

25 }

As declaracoes dos vectores desta extensao originam declaracoes de vectores unidimensionais

do mesmo tipo. O seu tamanho e calculado a partir da aplicacao da Expressao (3.1), referida na

Subseccao 3.2.2, aos tamanhos de cada dimensao, especificados na declaracao. Deste modo, a

semelhanca das declaracoes de vectores na linguagem C tradicional, o programador apenas pode

utilizar expressoes constantes para especificar o tamanho de cada dimensao do vector. Os vectores

gerados terao, por regra, a forma de vectores unidimensionais da linguagem C tradicional, conforme se

ilustra na Listagem 3.4.

24

Page 45: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Listagem 3.4: Soma dos elementos de duas matrizes (linguagem C tradicional).

1 #include <stdio.h>

2

3 int v[50][60];

4 int u[(50) * (60)];

5

6 int total(int mat1[50][60], int mat2[]) {

7 int i, j, res = 0;

8 for(i = 0; i < 50; ++i) {

9 for(j = 0; j < 60; ++j) {

10 res += mat1[i][j] + mat2[(i) + (j) * (50)];

11 }

12 }

13 return res;

14 }

15

16 int main() {

17

18 /* Inicializacao das matrizes

19 ...

20

21 */

22

23 printf("%d\n", total(v, u));

24 return 0;

25 }

Se o programador pretender utilizar reserva dinamica de memoria, deve para isso invocar a funcao

de reserva que pretender, atribuindo o valor retornado por essa funcao a uma variavel do seu pro-

grama cujo tipo seja um vector da extensao da linguagem. Dada a diferenca de tipos entre o retorno

das funcoes de reserva e estes vectores, devera ser utilizada uma operacao de type cast do valor

retornado1, como se ilustra na Listagem 3.5.

1Esta operacao e tipicamente utilizada apos uma chamada a uma funcao de reserva de memoria, para ser possıvel tratar oconteudo do bloco reservado com o tipo de dados que o mesmo se destina a guardar.

25

Page 46: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Listagem 3.5: Alteracao do tipo do vector retornado pela funcao de reserva.

1 #include <stdlib.h>

2

3 int main() {

4 int u[;];

5 void *ptr = malloc(50*60*sizeof(int));

6

7 /* Cast aplicado ao valor da variavel 'ptr' */

8 u = (int[50;60]) ptr;

9

10 /* Utilizacao do vector

11 ...

12

13 */

14

15 free((void *) u);

16 return 0;

17 }

Ao realizar esta operacao de type cast, o programador tera a garantia de que o bloco de memoria

retornado pela funcao de reserva que invocou sera processado segundo as regras dos vectores da

extensao da linguagem. No entanto, fica a sua responsabilidade a gestao dessa mesma memoria, bem

como a sua libertacao. De acordo com as regras de geracao de codigo referidas, e devido a incompa-

tibilidade existente entre vectores estaticos e ponteiros na linguagem C, o programador devera, neste

caso, declarar o vector sem especificar os tamanhos das suas dimensoes. Este tipo de declaracao em

particular ira originar um ponteiro no codigo tradicional gerado, ao inves de um vector unidimensional. A

especificacao das dimensoes devera realizar-se apenas aquando da operacao de type cast, conforme

ilustrado.

3.2.4 Exemplos de Utilizacao

Como ja foi referido, quando a arquitectura do sistema fornece multiplicacoes ao nıvel de hard-

ware, e quando o seu custo computacional e inferior ao custo das operacoes de carregamento de

enderecos, e esperado que, quanto maior o numero de dimensoes dos vectores utilizados, melhor se

revele o seu desempenho, quando comparados aos vectores existentes na linguagem C tradicional.

Quando esta operacao necessita de ser realizada por software, torna-se necessario estudar o numero

de multiplicacoes de ındices realizadas pelos novos vectores face ao numero de carregamentos de

enderecos realizados pelos vectores tradicionais.

26

Page 47: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Considere-se agora o excerto de codigo da Listagem 3.6, o qual realiza acessos a dois vectores

bidimensionais. De acordo com as regras de geracao de codigo referidas, a chamada a funcao printf

resultara na seguinte linha de codigo, a qual acede a mesma posicao de cada vector de modo diferente:

printf("%d\n%d\n", v[50][60], u[(50) + (60) * (100)];

Considerando esta linha, gerou-se o codigo assembly correspondente, com recurso a ferramenta

GNU Compiler Collection (GCC) numa arquitectura Intel x86. Atraves da observacao do codigo resul-

tante, apresentado na Listagem 3.7. Atraves da sua observacao, e possıvel constatar que o carrega-

mento de um valor do vector v, o qual e um vector da linguagem C tradicional, implica a realizacao de

dois carregamentos de enderecos, realizados pelas duas ocorrencias da instrucao: movl (%eax), %eax.

Estes carregamentos correspondem a aplicacao sucessiva dos deslocamentos a cada ponteiro carre-

gado.

Listagem 3.6: Acessos a vectores de ambos os tipos (linguagem C).

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 int **v;

5 int u[100;100];

6

7 int main() {

8 /* Reserva de memoria para 'v'

9 ...

10

11 */

12

13 printf("%d\n%d\n", v[50][60], u[50;60]);

14 return 0;

15 }

27

Page 48: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Listagem 3.7: Acessos a vectores de ambos os tipos (linguagem assembly).

1 movl u, %eax ; Ponteiro para o inicio de 'u'

2 addl $24200, %eax ; Soma do deslocamento a 'u'

3 ; d = (50+60*100)*4 bytes

4 movl (%eax), %edx ; Carregamento do endereco

5

6 movl v, %eax ; Ponteiro para o inicio de 'v'

7 addl $200, %eax ; Soma do deslocamento a 'v'

8 ; d1 = 50*4 bytes

9 movl (%eax), %eax ; Carregamento do endereco

10 addl $240, %eax ; Soma do deslocamento a 'v[50]'

11 ; d2 = 60*4 bytes

12 movl (%eax), %eax ; Carregamento do endereco

13

14 movl %edx, 8(%esp) ; Colocacao na pilha dos

15 movl %eax, 4(%esp) ; argumentos da funcao 'printf'

16 movl $.LC0, (%esp)

17 call printf

Por oposicao, o codigo assembly gerado pela operacao de indexacao do vector u, atraves da

aplicacao de um unico deslocamento ao ponteiro para a posicao inicial, revela-se mais curto, contendo

apenas um carregamento de endereco, realizado pela instrucao: movl (%eax), %edx.

Observa-se que a diferenca em termos de peso computacional de ambas as alternativas se prende

com a quantidade de operacoes de carregamento de enderecos geradas pelas operacoes com vecto-

res tradicionais, comparativamente as operacoes com os novos vectores. Estes carregamentos, iden-

tificaveis pela presenca de parentesis em torno de um dos operandos, ocorrem no codigo assembly

tantas vezes quanto o numero de dimensoes de um vector tradicional, mas apenas uma vez no codigo

resultante da extensao da linguagem.

Apresenta-se, na Listagem 3.8, um exemplo de codigo assembly gerado para uma operacao de

acesso a um vector tradicional com 6 dimensoes. Como esperado, neste caso, sao realizados 6 carre-

gamentos.

28

Page 49: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Listagem 3.8: Carregamento de um valor num vector com 6 dimensoes.

1 movl v, %eax

2

3 addl $200, %eax

4 movl (%eax), %eax

5

6 addl $240, %eax

7 movl (%eax), %eax

8

9 addl $280, %eax

10 movl (%eax), %eax

11

12 addl $320, %eax

13 movl (%eax), %eax

14

15 addl $360, %eax

16 movl (%eax), %eax

17

18 addl $400, %eax

19 movl (%eax), %eax ; Carregamento de

20 ; v[50][60][70][80][90][100]

Outra vantagem desta abordagem, a qual se observa na operacao de soma do deslocamento de

24200 bytes ao ponteiro para u, e a possibilidade de pre-processamento e optimizacao (pelo compila-

dor da linguagem C tradicional) das operacoes aritmeticas associadas as somas e multiplicacoes que

constituem o calculo desse mesmo deslocamento. Neste caso, visto que o acesso e realizado apenas

atraves de literais, todo o calculo pode ser realizado em tempo de compilacao, minimizando o custo

computacional em tempo de execucao. O mesmo e valido para qualquer tipo de expressao constante.

Alem desta optimizacao, como ja foi referido anteriormente, e de considerar a equivalencia existente

entre uma operacao de multiplicacao por uma potencia da forma 2n, para n > 0, e uma sequencia de n

operacoes de deslocamento a esquerda dos bits de um registo do processador. O custo computacional

deste tipo de operacoes e normalmente muito inferior ao de uma multiplicacao, pelo que, quando o

calculo de um deslocamento envolve multiplicacoes com operandos multiplos de 2, torna-se possıvel

decompo-la em deslocamentos a esquerda e multiplicacoes mais simples ou somas. Isto possibilita

diminuir o custo total do calculo em arquitecturas que nao fornecam a operacao de multiplicacao ao

nıvel de hardware. Aos exemplos ilustrados podem juntar-se problemas da area de calculo matricial,

como o calculo de produtos de matrizes, inversas de matrizes, determinantes, entre outros.

29

Page 50: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

3.3 Metodologia de Avaliacao

Nesta seccao, apresentam-se os requisitos a que se sujeitou o processo de avaliacao da solucao

desenvolvida.

A correcta avaliacao da solucao exige medir os tempos medios de execucao de programas que

utilizem somente vectores tradicionais da linguagem C, comparando-os com os tempos medios de

execucao de programas identicos, em que apenas se substituam os vectores tradicionais por vectores

da extensao da linguagem.

Estas medicoes devem ser realizadas em sistemas com arquitecturas de CPU distintas, nomeada-

mente ARM e Intel, e com diferentes velocidades de relogio. Deste modo, torna-se possıvel concluir

sobre a influencia destes factores no desempenho da solucao. Idealmente, deve ser minimizado o

numero de processos em execucao concorrente nos sistemas de teste, de modo a que as medicoes de

desempenho sejam tao fiaveis quanto possıvel.

Os programas de teste devem incluir vectores com numeros de dimensoes iguais ou superiores a 2,

e com tamanhos tao elevados quanto possıvel, dependendo da quantidade de memoria disponıvel em

cada arquitectura.

Com esta metodologia, pretende-se obter e concluir sobre os racios de desempenho dos vectores da

extensao da linguagem face ao desempenho dos vectores tradicionais, em cada arquitectura referida.

3.4 Sumario

A solucao desenvolvida consiste num compilador que processa codigo escrito numa versao esten-

dida da linguagem C, a qual inclui vectores que replicam o comportamento dos mesmos na linguagem

Fortran. O codigo produzido por este compilador e codigo C tradicional, o que permite que o mesmo

seja processado por um compilador da linguagem ja existente.

A operacao de indexacao dos novos vectores e sempre realizada atraves do calculo de um deslo-

camento aplicado ao endereco da posicao inicial de cada vector, de modo a obter-se o comportamento

pretendido. Toda a restante funcionalidade da linguagem C mantem-se inalterada, de modo a possibili-

tar ao programador a escolha dos vectores que pretende utilizar em cada situacao. Essa decisao devera

depender das especificacoes do hardware disponıvel para a execucao dos programas desenvolvidos,

tendo em conta o desempenho comparativo de cada tipo de vectores nessas condicoes.

A sintaxe associada aos novos vectores e semelhante a ja existente para os vectores da linguagem

C. Dependendo das condicoes de hardware disponıveis, o programador podera alternar entre ambos

os tipos de vectores, de modo a maximizar a eficiencia dos seus programas.

30

Page 51: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

4Realizacao

Conteudo

4.1 Funcionalidade da Solucao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

4.2 Flex: Fast Lexical Analyzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.3 GNU Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.4 Descricao Gramatical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

4.5 Semantica e Geracao de Codigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4.6 Processo de Desenvolvimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.7 Problemas Enfrentados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

31

Page 52: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

32

Page 53: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Neste capıtulo e descrito o processo de desenvolvimento da solucao proposta, referindo-se as tec-

nologias e ferramentas utilizadas na concepcao da solucao.

Descrevem-se ainda as principais dificuldades e problemas encontrados ao longo deste processo.

4.1 Funcionalidade da Solucao

A ferramenta desenvolvida consiste numa aplicacao que recebe uma sequencia de entrada atraves

do canal standard input, produzindo uma sequencia de saıda no canal standard output. Como ja foi

referido, a entrada da aplicacao devera ser codigo escrito na versao estendida da linguagem C. A

saıda produzida pode entao ser visualizada na interface de linha de comandos utilizada para executar

a aplicacao, ou redireccionada para um ficheiro de codigo fonte da linguagem C tradicional.

O codigo gerado pela ferramenta desenvolvida consiste numa copia integral do codigo recebido

como entrada, com excepcao das operacoes referentes aos vectores que constituem a extensao da

linguagem. O codigo em comentario nao e processado, sendo tambem integralmente copiado para o

canal de saıda da aplicacao.

O compilador produzido suporta mudancas de ambiente de nomes, sendo possıvel a declaracao de

vectores da extensao da linguagem num determinado ambiente, realizando a indexacao num ambiente

de nıvel inferior. A indexacao em ambientes de nıvel superior nao e possıvel. A criacao de um ambiente

de nomes da-se quando o programador inicia um bloco de codigo, constituıdo por um conjunto de

instrucoes entre chavetas. Um bloco de instrucoes pode ou nao corresponder ao corpo de uma funcao

ou instrucao de controlo de fluxo, como um ciclo ou instrucao condicional. Caso existam, em ambientes

de nomes diferentes, duas ou mais variaveis com o mesmo nome, a indexacao referenciara a variavel

que se encontre no ambiente de nomes de nıvel mais baixo. A semelhanca dos vectores tradicionais, as

operacoes de indexacao podem ser encadeadas, utilizando o valor retornado por uma destas operacoes

como ındice de outra.

E suportada a definicao de tipos de dados em tempo de compilacao, com recurso a instrucao

typedef. Deste modo, e possıvel a declaracao, indexacao e passagem como argumento de vecto-

res com tipos definidos pelo programador. Estes poderao ser tipos primitivos da linguagem, ponteiros,

estruturas ou unioes.

A definicao de funcoes pode incluir, na sua lista de argumentos, vectores da extensao da linguagem

com qualquer numero de dimensoes. Quando tal acontece, e necessaria a especificacao do tamanho

de cada dimensao, com excepcao do ultimo. De modo semelhante, e possıvel a definicao de funcoes

cujos argumentos sejam ponteiros para outras funcoes, as quais podem, por sua vez, receber vectores

da extensao desenvolvida como argumentos. Tambem e possıvel a definicao de funcoes cujo valor de

retorno seja um ponteiro para uma funcao com vectores da extensao na lista de argumentos.

33

Page 54: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Por ultimo, como ja foi referido e exemplificado, e ainda possıvel a utilizacao e tratamento de pon-

teiros como vectores da extensao da linguagem. Deste modo, blocos de memoria reservada atraves

de funcoes de reserva da linguagem C podem ser convertidos em vectores da extensao. A conversao

realiza-se atraves de uma operacao de type cast aplicada a um ponteiro. No entanto, o resultado de

uma operacao deste tipo apenas pode ser atribuıdo a um vector da extensao que tenha sido decla-

rado sem qualquer especificacao de tamanhos das suas dimensoes. O tipo de dados especificado na

operacao de type cast devera ser igual ao tipo desse vector.

A Listagem 4.1 constitui uma possıvel sequencia de entrada da aplicacao desenvolvida, ilustrando

aspectos da funcionalidade descrita. A sequencia de saıda resultante do processamento apresenta-se

na Listagem 4.2.

Listagem 4.1: Exemplo de entrada do compilador.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 int ext array[6; 10; 20]; // Variavel global

5

6 int foo(int arg1, int *arg2[30; 50;], double arg3) {

7

8 /* Declaracoes */

9 int *ptr;

10 int ext array[3; 5; 10]; // Nome igual ao da variavel global

11 int trad array[4][6][11];

12 int cast array[;];

13

14 /* Indexacao dos vectores declarados localmente */

15 printf("%d\n", ext array[2; 4; 9] + trad array[3][5][10]);

16

17 /* Indexacao de um argumento; tamanho da ultima dimensao desnecessario */

18 ptr = arg2[29; 49; 99];

19

20 /* Encadeamento de indexacoes */

21 trad array[3 + ext array[3; ext array[0; 0; 0]; 10]][5][10];

22

23 /* Utilizacao de reserva dinamica de memoria */

24 ptr = (int *) malloc(45*sizeof(int));

25 cast array = (int [9; 5]) ptr; // Operacao de type cast

34

Page 55: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

26 printf("%d\n", cast array[8; 4]);

27 free(cast array);

28

29 return 0;

30 }

31

32 int main(int argc, char **argv) {

33 printf("%d\n", ext array[5; 9; 19]); // Indexacao da variavel global

34 int *arg array[30; 50; 100];

35 return foo(1, arg array, 3.14);

36 }

Listagem 4.2: Exemplo de saıda do compilador.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 int ext array[(6) * (10) * (20)]; // Variavel global

5

6 int foo(int arg1, int *arg2[], double arg3) {

7

8 /* Declaracoes */

9 int *ptr;

10 int ext array[(3) * (5) * (10)]; // Nome igual ao da variavel global

11 int trad array[4][6][11];

12 int *cast array;

13

14 /* Indexacao dos vectores declarados localmente */

15 printf("%d\n", ext array[(2) + (4) * (3) + (9) * (3) * (5)]

16 + trad array[3][5][10]);

17

18 /* Indexacao de um argumento; tamanho da ultima dimensao desnecessario */

19 ptr = arg2[(29) + (49) * (30) + (99) * (30) * (50)];

20

21 /* Encadeamento de indexacoes */

22 trad array[3 + ext array[(3) +

23 (ext array[(0) + (0) * (3) + (0) * (3) * (5)]) * (3) +

24 (10) * (3) * (5)]][5][10];

35

Page 56: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

25

26 /* Utilizacao de reserva dinamica de memoria */

27 ptr = (int *) malloc(45*sizeof(int));

28 cast array = (int *) ptr; // Operacao de type cast

29 printf("%d\n", cast array[(8) + (4) * (9)]);

30 free(cast array);

31

32 return 0;

33 }

34

35 int main(int argc, char **argv) {

36 printf("%d\n",

37 ext array[(5) + (9) * (6) +

38 (19) * (6) * (10)]); // Indexacao da variavel global

39 int *arg array[(30) * (50) * (100)];

40 return foo(1, arg array, 3.14);

41 }

4.2 Flex: Fast Lexical Analyzer

A ferramenta escolhida para a realizacao da analise lexical da solucao foi a ferramenta Flex. Esta

ferramenta e de utilizacao livre, de acordo com a GNU General Public License (GPL), pelo que nao sao

impostas quaisquer restricoes ou condicoes de uso a este projecto [11].

A ferramenta Flex permite gerar codigo-fonte nas linguagens C ou C++. Este, quando compilado,

produz um programa analisador de sequencias de entrada. O comportamento do analisador gerado e

definido por uma descricao contida num ficheiro fornecido a esta ferramenta. A descricao deve mapear

expressoes regulares em blocos de codigo C ou C++, dependendo da linguagem escolhida, os quais

sao executados pelo analisador lexical quando este identifica correspondencias entre a sequencia de

entrada e as expressoes regulares contidas no ficheiro de descricao [11]. Concretamente, cada bloco

de codigo consiste em converter num lexema (ou token) cada correspondencia entre a sequencia de

entrada e as expressoes regulares do ficheiro de descricao do analisador lexical. Os lexemas sao pro-

cessados pelo analisador sintactico pela mesma ordem em que sao reconhecidos ao nıvel do analisador

lexical, e podem ou nao ter um valor adicional associado, caso este seja necessario ao processamento

do lexema ao nıvel da analise sintactica [11]. O uso desta ferramenta permite complementar o compor-

tamento do analisador lexical produzido, atraves da ferramenta escolhida para a realizacao da restante

funcionalidade da solucao, que se descreve na seccao seguinte.

36

Page 57: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

4.3 GNU Bison

Como ja foi referido na Seccao 3.1, para desenvolver o analisador sintactico, optou-se pela utilizacao

da ferramenta GNU Bison. Esta ferramenta, devido a sua natureza open source [11], permitiu testar a

correcta execucao da solucao em diferentes sistemas operativos.

A ferramenta Bison permite gerar programas de analise sintactica, nomeadamente analisadores

do tipo Look-Ahead Left-to-Right (LALR), complementando a funcionalidade da ja referida ferramenta

Flex [11, 17]. O comportamento dos analisadores sintacticos gerados provem de uma gramatica livre

de contexto, que devera ser fornecida como entrada da ferramenta Bison. O analisador sintactico e

responsavel pelo processamento sequencial de cada lexema proveniente do analisador lexical, identifi-

cando correspondencias entre os lexemas recebidos e as producoes das regras da gramatica fornecida

a ferramenta Bison [11].

Para este efeito, o analisador sintactico constroi um automato finito determinista que depende da

gramatica fornecida [17], e utiliza uma estrutura de dados com comportamento “last in, first out” (uma

pilha) para guardar os lexemas reconhecidos pelo analisador lexical [11]. Cada estado do automato

corresponde a um conjunto de lexemas reconhecidos e guardados na pilha do analisador sintactico

num dado momento, e cada transicao corresponde a uma operacao que deve ser realizada quando

o lexema seguinte e recebido. As operacoes que o automato realiza podem ser de deslocamento ou

de reducao. Uma operacao de deslocamento consiste na decisao de armazenar na pilha o lexema

recebido, transitando para um novo estado que acrescenta esse lexema ao conjunto de lexemas reco-

nhecidos [11,17]. Uma operacao de reducao ocorre quando e verificada uma correspondencia entre o

conjunto de lexemas reconhecidos e uma producao da gramatica que originou o automato. Neste caso,

da-se tambem uma transicao no automato, mas sao retirados da pilha os lexemas que constituem a

producao, reduzindo-se o tamanho da pilha [11,17].

Ao elaborar uma gramatica, e possıvel a existencia de regras que introduzam ambiguidade no

automato do analisador sintactico, ou seja, e possıvel a ocorrencia de conflitos no automato, que

possibilitem mais do que uma opcao de transicao de estado quando e reconhecido um mesmo le-

xema. Concretamente, e possıvel a ocorrencia de dois tipos de conflitos: deslocamento/reducao e

reducao/reducao [11].

Os conflitos do tipo deslocamento/reducao ocorrem quando um mesmo lexema pode, simultanea-

mente, provocar uma operacao de reducao, de acordo com uma producao presente na gramatica, ou

uma operacao de deslocamento, para mais tarde realizar uma operacao de reducao diferente, de acordo

com outra producao [11]. Um conflito de reducao/reducao ocorre quando um mesmo lexema permite

realizar duas operacoes de reducao diferentes, cada uma de acordo com uma producao diferente da

gramatica [11].

Os analisadores gerados pela ferramenta Bison classificam-se como analisadores LALR(1) [11,17].

37

Page 58: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tratam-se de analisadores que percorrem a sequencia de lexemas no sentido da esquerda para a

direita, utilizando, em cada estado do automato, o lexema seguinte da sequencia em analise como

informacao auxiliar a resolucao de conflitos. Esta informacao, designada por lookahead, e util na

resolucao de conflitos do tipo deslocamento/reducao, pois pode permitir ao analisador determinar se a

operacao mais adequada numa situacao de conflito, dado um lexema de lookahead, e um deslocamento

ou uma reducao [11, 17]. Quanto maior a sequencia de lookahead, mais informacao e disponibilizada

ao analisador, e consequentemente, maior e tambem a sua capacidade de resolucao de conflitos deste

tipo1. Porem, uma sequencia de lookahead com mais do que um lexema provoca um aumento expo-

nencial no numero de estados do automato de um analisador, o que prejudica a sua viabilidade. Este

compromisso constitui a base da decisao de implementacao da ferramenta Bison como gerador de

analisadores sintacticos LALR(1) [17].

A gramatica fornecida a ferramenta Bison devera mapear as producoes das regras sintacticas em

blocos de instrucoes, os quais sao executados quando e realizada uma operacao de reducao. No caso

de a gramatica fornecida originar conflitos de deslocamento/reducao, o automato transita, por omissao,

para o estado correspondente a realizacao da operacao de deslocamento [11]. Quando ocorre um con-

flito de reducao/reducao, a transicao correspondera a regra da gramatica que ocorre em primeiro lugar

no ficheiro que a descreve [11]. Apesar de a sua ocorrencia nao impedir a compilacao do programa,

deve ser evitada a existencia de conflitos na gramatica, pois o automato resultante podera provocar

comportamentos indesejados por parte do analisador sintactico [11].

4.4 Descricao Gramatical

O ficheiro de descricao gramatical elaborado possui regras que, a medida que ocorrem operacoes

de reducao do analisador sintactico, produzem o codigo C tradicional a ser gerado. Este codigo e

armazenado em memoria sob a forma de cadeias de caracteres sucessivamente mais longas. Estas

cadeias de caracteres sao uma copia da entrada do compilador desenvolvido, com excepcao do codigo

respeitante aos vectores da extensao da linguagem C, o qual e modificado de acordo com as regras

sintacticas escolhidas para a solucao, mencionadas anteriormente, e com o seu significado semantico.

Da regra principal da gramatica elaborada, a qual especifica as primeiras ramificacoes da arvore

sintactica da solucao, fazem parte quatro producoes de maior destaque que as restantes, pois dizem

respeito as operacoes essenciais dos vectores da extensao desenvolvida. Estas operacoes, referidas

anteriormente, sao nomeadamente a declaracao, indexacao, passagem como argumento de funcao e

type cast de vectores da extensao da linguagem C.

A indexacao de um vector e sintacticamente semelhante a uma operacao de declaracao, sendo

1De forma generica, um analisador LALR(k) utiliza k lexemas de lookahead.

38

Page 59: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

constituıda pelo nome atribuıdo ao vector, ao qual se seguem os ındices indicados pelo programador,

entre parentesis rectos e separados pelo sımbolo ponto e vırgula. A sintaxe da operacao de declaracao

inclui a sintaxe da indexacao, precedendo-a apenas pelo tipo de dados escolhido para o vector que se

pretende declarar. Estas operacoes recorrem a uma estrutura de dados, do tipo struct symbol, a qual

associa o nome dado a um determinado vector da extensao aos tamanhos das dimensoes que lhe sao

atribuıdas na sua declaracao.

De um modo geral, procurou-se reproduzir as regras sintacticas descritas na Subseccao 3.2.1, de

forma tao fiel quanto possıvel. Porem, a elaboracao da descricao gramatical revelou-se mais complexa

do que inicialmente esperado, devido ao requisito de nao introduzir incompatibilidades com a sintaxe

da linguagem C tradicional, como se vera na Seccao 4.7.

4.5 Semantica e Geracao de Codigo

As estruturas do tipo struct symbol sao organizadas em memoria sob a forma de uma lista ligada,

a qual constitui a tabela de sımbolos para um determinado ambiente (scope) do programa. Cada tabela

de sımbolos constitui, por sua vez, um elemento do tipo struct scope. Este tipo de dados organiza-se

em memoria sob a forma de uma pilha, sendo criada uma nova entrada de cada vez que e reconhecida

a existencia de um novo ambiente local. Quando o codigo do novo ambiente termina, e removida

a entrada da pilha criada mais recentemente. Esta pilha possui sempre, no mınimo, uma entrada,

correspondente ao ambiente global do programa.

A traducao de uma operacao de declaracao em codigo C tradicional corresponde a declaracao de

um vector tradicional unidimensional, cujo tamanho e o produto de todos os tamanhos especificados

para cada dimensao do vector da extensao. O reconhecimento de uma operacao deste tipo tem como

resultado o acrescimo de uma nova entrada na tabela de sımbolos do ambiente no topo da pilha de

elementos do tipo struct symbol.

Algoritmo 4.1: Geracao de codigo de uma declaracao.begin

tamanhos←− entrada.tamanhoscodigo←− εAcrescentaSimbolo(entrada, tabela)

while TemElementos(tamanhos) do

Concatena(codigo, '(' +indices.elementoActual+ ')' )tamanhos←− tamanhos.proximoElemento

if TemElementos(tamanhos) thenConcatena(codigo, '*' )

39

Page 60: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

O reconhecimento da ocorrencia da definicao de uma funcao que receba como argumento um vector

da extensao desenvolvida introduz tambem alteracoes na tabela de sımbolos do programa. Porem,

neste caso, os sımbolos de cada vector da lista de argumentos da funcao sao salvaguardados num

novo ambiente, que corresponde ao ambiente local da funcao.

A indexacao de um vector depende da presenca do seu nome na tabela de sımbolos, pois apenas e

possıvel gerar o codigo correspondente a esta operacao com recurso a informacao sobre os tamanhos

das dimensoes do vector, obtida atraves do acesso a entrada correspondente da tabela de sımbolos

que a contem. A procura de um nome para obtencao da informacao necessaria a geracao do codigo da

operacao de indexacao da-se a partir do topo da pilha de ambientes do programa. E percorrida cada

tabela de sımbolos ate se obter a primeira correspondencia, momento apos o qual a procura termina e

e realizada a geracao do codigo, de acordo com o Algoritmo 4.2. A informacao necessaria a geracao

do codigo da operacao encontra-se presente na lista de ındices introduzidos pelo programador, bem

como na lista de dimensoes do vector a indexar, contida na estrutura de dados resultante da procura.

Algoritmo 4.2: Geracao de codigo de uma indexacao.begin

simbolo←− ProcuraSimbolo(entrada.nome, tabela)tamanhos←− simbolo.tamanhosindices←− entrada.indicescodigo←− εcontadorIndices←− 0limiteIndices←− 0

while TemElementos(tamanhos) and TemElementos(indices) do

if limiteIndices > 0 thenConcatena(codigo, '+' )

Concatena(codigo, '(' +indices.elementoActual+ ')' )

while contadorIndices < limiteIndices doConcatena(codigo, '*' + '(' +tamanhos.elementoActual+ ')' )tamanhos←− tamanhos.proximoElementocontadorIndices←− contadorIndices+ 1

tamanhos←− tamanhos.primeiroElementoindices←− indices.proximoElementocontadorIndices←− 0limiteIndices←− limiteIndices+ 1

Quando e realizada uma tentativa de indexacao de um vector que nao tenha sido declarado no am-

biente em que a mesma se realiza, ou seja, quando a procura de um sımbolo nas tabelas de sımbolos

do programa nao tem sucesso, e indicado um erro semantico ao programador, e o processamento e

abortado.

Por fim, a realizacao de uma operacao de type cast de um ponteiro so e considerada valida se o

40

Page 61: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

mesmo tiver sido declarado sem especificacao dos tamanhos das suas dimensoes, conforme ilustrado

no exemplo da Listagem 3.5 da Subseccao 3.2.3. Este tipo de declaracao origina uma operacao de

declaracao de um ponteiro no codigo gerado, ao inves de um vector unidimensional. O ponteiro gerado

tem o mesmo tipo do vector declarado, e a tabela de sımbolos e, neste caso, actualizada apenas com

informacao sobre o nome da variavel declarada.

A operacao de type cast em si, tal como no exemplo referido, e realizada atraves do uso, entre

parentesis, do tipo de vector pretendido, juntamente com a especificacao dos tamanhos das dimensoes

do vector. O reconhecimento desta operacao origina uma procura nas tabelas de sımbolos semelhante

a que e realizada para gerar o codigo de uma operacao de indexacao. Porem, esta procura serve

para acrescentar a informacao acerca das dimensoes do vector a entrada correspondente, possibili-

tando a partir daı a realizacao de indexacoes. Caso haja uma tentativa de indexacao de um vector

cujas dimensoes nao tenham sido especificadas, o processamento termina com a indicacao de um erro

semantico.

4.6 Processo de Desenvolvimento

O processo de desenvolvimento comecou com a observacao e analise de exemplos de ficheiros de

descricao lexical e gramatical, respectivamente destinados as ferramentas Flex e Bison, para a lingua-

gem C tradicional. Isto permitiu a familiarizacao e aprendizagem de regras sintacticas da linguagem

C passıveis de interferir com as regras da solucao desenvolvida. De especial destaque sao as regras

relativas ao reconhecimento de operacoes com vectores tradicionais, as quais tiveram de ser replica-

das no ficheiro de descricao gramatical da solucao, de modo a evitar erros sintacticos provenientes da

utilizacao de vectores tradicionais pelo programador.

Para desenvolver o codigo da solucao, atraves das ferramentas Flex e Bison, optou-se pela lingua-

gem C. Essa mesma linguagem foi utilizada tambem para a criacao de uma biblioteca de funcoes de

auxılio ao processamento da entrada da solucao, realizacao de validacoes semanticas e construcao das

sequencias de saıda. As funcoes da biblioteca em questao sao invocadas quer no codigo da descricao

lexical da ferramenta Flex, quer no codigo da descricao gramatical da ferramenta Bison.

4.6.1 Tipos

Concretamente, no que diz respeito a descricao lexical, revelou-se importante o reconhecimento de

algumas palavras reservadas da linguagem C, nomeadamente os sımbolos que designam os tipos da

linguagem. Estes sımbolos, como se vera mais adiante, sao importantes para distinguir sintacticamente

as operacoes de declaracao de vectores das operacoes de indexacao. Nao so os sımbolos que desig-

nam tipos, como int, char ou double, mas tambem os sımbolos struct, union e typedef, pela relacao

41

Page 62: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

que tem com as anteriores, se revelaram importantes na analise sintactica. Numa primeira abordagem,

optou-se por distinguir com um lexema diferente cada sımbolo referente a um tipo da linguagem. Na

versao final, porem, visto que essa distincao se revelou desnecessaria, apenas os sımbolos struct,

union e typedef possuem lexemas unicos. Todos os outros, ao serem reconhecidos, produzem um

lexema que designa genericamente um tipo, sem o especificar.

4.6.2 Identificadores

Revelou-se igualmente importante o reconhecimento de sımbolos alfanumericos, com o acrescimo

do caracter underscore, para realizar o reconhecimento de identificadores de variaveis. Estes sımbolos

constituem possıveis nomes para os vectores a processar pelo compilador desenvolvido, e sao tambem

identificados com um lexema proprio. Para o processamento das definicoes de funcoes, foi necessario

reconhecer, alem destes, os sımbolos: vırgula, parentesis curvos, chavetas e reticencias. Por fim, o

processamento dos vectores em si, de acordo com a sintaxe escolhida para os mesmos, exigiu ainda o

reconhecimento dos sımbolos: parentesis rectos e ponto e vırgula. Cada lexema produzido e comuni-

cado ao analisador sintactico faz-se sempre acompanhar pelo texto efectivamente reconhecido, sob a

forma de um atributo, uma vez que a geracao de codigo produzira, na sua maioria, texto semelhante,

ou mesmo igual a sequencia de entrada.

4.6.3 Comentarios

Optou-se por nao processar texto em comentario no codigo-fonte da linguagem estendida, pelo que

se realiza tambem o reconhecimento dos sımbolos da linguagem C que indicam o inıcio e final de co-

mentarios. Estes lexemas em particular provocam uma alteracao de estado do analisador lexical. Neste

estado, sao ignoradas todas as regras definidas no ficheiro de descricao lexical, produzindo-se sempre

o mesmo lexema, independentemente do texto recebido como entrada. Este lexema indica ao anali-

sador sintactico que deve ser copiado o texto recebido, integralmente e sem qualquer processamento.

As excepcoes a este comportamento sao os sımbolos da linguagem C que indicam o final do texto em

comentario, fazendo com que o analisador lexical recupere o seu comportamento regular.

4.6.4 Declaracoes

Na analise sintactica, como ja foi referido, sao utilizados os lexemas provenientes da analise lexi-

cal para emparelhar sequencias dos mesmos, recebidas como entrada, com as regras definidas na

descricao gramatical. As regras de declaracao de vectores tem por base as regras de indexacao,

sendo apenas acrescentada uma lista de tipos que a antecede, e que permite distinguir entre as duas

operacoes. Quando o analisador sintactico realiza uma operacao de reducao de acordo com a regra

42

Page 63: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

de declaracao de um vector, o codigo gerado corresponde a declaracao de um vector tradicional do

mesmo tipo, com uma unica dimensao, e cujo tamanho corresponde ao produto de todas as dimensoes

indicadas pelo programador. A estrutura do tipo struct symbol correspondente e entao criada, arma-

zenando uma cadeia de caracteres, que contem o nome da variavel declarada, bem como uma lista

ligada de outras cadeias de caracteres. Estas outras cadeias contem o texto que o programador utilizou

para especificar os tamanhos das dimensoes do vector declarado. A estrutura de dados produzida e

entao guardada de imediato na estrutura de dados que constitui a tabela de sımbolos do programa,

tambem ela uma lista ligada, que armazena, em cada entrada, uma entidade do tipo struct symbol.

Optou-se por nao realizar qualquer reconhecimento de expressoes nem validacoes semanticas para

determinar o valor das dimensoes especificadas numa operacao de declaracao, pois o codigo C tradici-

onal correspondente as operacoes de indexacao destes vectores pode ser gerado independentemente

do valor semantico dos sımbolos introduzidos pelo programador, sejam eles literais numericos, ex-

pressoes, variaveis, chamadas de funcoes, constantes ou outros sımbolos. Cabe, portanto, ao compila-

dor da linguagem C tradicional a validacao semantica dos sımbolos introduzidos como dimensoes dos

vectores da extensao da linguagem.

4.6.5 Indexacoes

Quando uma operacao de reducao se da de acordo com a regra de indexacao de um vector, e

realizada uma procura pela primeira ocorrencia de uma entidade do tipo struct symbol cujo nome

corresponda a variavel indexada. Como ja foi referido, a procura tem inıcio no ambiente em que a

indexacao se realiza, percorrendo-se a pilha de ambientes sucessivamente, ate ser atingido o ambi-

ente global. Quando uma procura nao obtem nenhum resultado, a indexacao nao e possıvel, pelo que

e indicado um erro semantico e a geracao de codigo e interrompida. Quando e encontrada uma cor-

respondencia, obtem-se a lista de dimensoes indicadas na declaracao da variavel, que se encontra

guardada na entidade do tipo struct symbol correspondente. Procede-se entao a geracao do codigo

C tradicional para calcular o ındice pretendido. O codigo e gerado de acordo com a Expressao (3.2),

mencionada na Subseccao 3.2.2, e com o Algoritmo 4.2.

4.6.6 Funcoes

No que diz respeito a definicao de funcoes, uma reducao de acordo com a regra correspondente da

gramatica realiza o equivalente a uma operacao de declaracao por cada vector da extensao passado

como argumento da funcao definida. No entanto, ao inves de especificar o seu tamanho como o pro-

duto de todas as dimensoes do vector, o codigo C tradicional gerado nao inclui qualquer informacao

a esse respeito, visto que os vectores tradicionais originados sao unidimensionais. Como ja se referiu

43

Page 64: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

anteriormente, a linguagem C permite a omissao do tamanho da primeira dimensao de vectores pas-

sados como argumento de funcoes, pelo que, neste caso, essa informacao e inteiramente ignorada. A

definicao de uma funcao e tambem responsavel pela criacao de um novo ambiente de nomes, sob a

forma de uma nova estrutura do tipo struct scope, a qual e acrescentada ao topo da pilha de ambi-

entes de nomes. Os nomes dos vectores passados como argumentos sao entao incluıdos neste novo

ambiente, ficando assim disponıveis para operacoes de indexacao no corpo da funcao.

De modo semelhante as definicoes de funcoes, tambem qualquer bloco de instrucoes delimitado por

chavetas origina a criacao de um novo ambiente de nomes. Por associacao, este caso inclui ocorrencias

de instrucoes de controlo de fluxo, como ciclos e instrucoes condicionais, quando as mesmas sao

sucedidas por blocos de instrucoes.

4.7 Problemas Enfrentados

O desenvolvimento do analisador sintactico da solucao suscitou obstaculos a programacao, nome-

adamente a ocorrencia de conflitos na gramatica produzida, entre outros problemas, que a seguir se

descrevem.

A linguagem C tradicional permite a utilizacao de sequencias arbitrarias de caracteres de mudanca

de linha, espacos em branco ou tabulacoes, sem que a sua presenca tenha qualquer influencia na

analise sintactica da linguagem. Dada a natureza da solucao desenvolvida, de modo a preservar a

legibilidade do codigo gerado a partir do codigo da extensao da linguagem, tornou-se requisito da

solucao a replicacao dessas mesmas sequencias de caracteres de forma tao fiel quanto possıvel. Para

o efeito, optou-se inicialmente por realizar o reconhecimento destes caracteres ao nıvel da analise le-

xical, processando-os como lexemas integrantes nas regras gramaticais da analise sintactica. Esta

abordagem originou a ocorrencia de numerosos conflitos na gramatica produzida, pois requeria a in-

clusao destes lexemas em todas as regras gramaticais. Isto levou a introducao de conflitos na gramatica

resultante, o que tornou inviavel o compromisso entre permissividade destes caracteres e correcta fun-

cionalidade da solucao.

Numa segunda abordagem, optou-se pela utilizacao de um vector de caracteres, partilhado pelos

analisadores lexical e sintactico, utilizado para acumular os referidos caracteres a medida que sao reco-

nhecidos na fase de analise lexical. Ao ser reconhecido um lexema, a sua comunicacao ao analisador

sintactico faz-se acompanhar pela concatenacao dos caracteres guardados no vector com o texto que

constitui o lexema. Esta estrategia torna possıvel a geracao de codigo com indentacao semelhante ao

codigo recebido como entrada da solucao, satisfazendo o requisito de preservacao da legibilidade do

mesmo. O uso desta abordagem obrigou, no entanto, a cuidados especiais na procura de sımbolos

nas tabelas de sımbolos, pois e essencial para isso considerar apenas os caracteres alfanumericos e

44

Page 65: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

underscore, descartando os restantes.

Uma outra dificuldade encontrada consistiu na incorrecta identificacao de lexemas que constituem

tipos de dados definidos em tempo de compilacao, pois os sımbolos que lhes dao origem nao sao

palavras reservadas da linguagem C tradicional. Por este motivo, ao nıvel da analise lexical, os mes-

mos produziam lexemas correspondentes a identificadores de variaveis, que provocavam a deteccao

de erros sintacticos em sequencias de entrada que deveriam ser consideradas validas pelo analisa-

dor sintactico. Para resolver este problema, tornou-se essencial o processamento de operacoes de

definicao de tipos, acrescentando regras a gramatica para o processamento do uso da palavra reser-

vada typedef. Optou-se pela criacao de uma lista ligada de cadeias de caracteres, partilhada por

ambos os analisadores. Esta lista e preenchida pelo analisador sintactico quando este realiza uma

operacao de reducao de acordo com a regra correspondente a uma definicao de tipo, guardando-se o

nome do tipo definido. Ao reconhecer um sımbolo candidato a producao de um lexema identificador

de variavel, o analisador lexical pode entao aceder a esta lista, para determinar se o mesmo foi previ-

amente definido como tipo. A decisao sobre o lexema a produzir da-se conforme o texto reconhecido

esteja ou nao presente na lista de tipos definidos pelo programador.

Ainda no que diz respeito ao reconhecimento de tipos de dados, surgiram dificuldades na distincao

entre analise sintactica e semantica das listas de tipos introduzidas nas operacoes de declaracao de

vectores. Inicialmente, optou-se por distinguir sintacticamente os sımbolos referentes a tipos, como

int, char ou float, e modificadores de tipos, como long, short ou unsigned. Esta distincao a nıvel

sintactico nao se revelou possıvel, pois exigia a validacao de todas as permutacoes possıveis de tipos

e modificadores, atraves da criacao de uma regra na gramatica para cada caso. Era necessario permi-

tir tambem o uso de apenas modificadores, sem tipo. Esta particularidade foi responsavel pela vasta

introducao de conflitos de deslocamento/reducao na gramatica. Na realidade, este tipo de verificacoes

deve ser feito a nıvel da analise semantica, testando apenas nessa fase a validade da sequencia in-

troduzida como lista de tipos que qualificam uma variavel. Por este motivo, optou-se por considerar

sintacticamente valida qualquer sequencia de lexemas de tipo, o que tornou a sua distincao desne-

cessaria tambem a nıvel lexical. A validacao semantica dessas sequencias e entao delegada para o

compilador da linguagem C tradicional utilizado juntamente com a solucao desenvolvida.

Inicialmente, surgiram tambem conflitos na gramatica como consequencia do processamento de

vectores unidimensionais, quer tradicionais, quer da extensao desenvolvida. As regras gramaticais

referentes ao processamento de ambos os tipos de vectores incluıam o caso em que o numero de

dimensoes e igual a um, apesar da sua igualdade sintactica e semantica. Esta sobreposicao originou

conflitos de reducao/reducao, os quais foram resolvidos atraves da remocao deste caso particular no

processamento de vectores da extensao da linguagem.

45

Page 66: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

46

Page 67: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

5Avaliacao da Solucao

Conteudo

5.1 Modelos de Teste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

5.2 Discussao dos Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

47

Page 68: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

48

Page 69: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Para testar a solucao desenvolvida, criaram-se alguns exemplos de algoritmos que realizam opera-

coes com matrizes. Os mesmos foram implementados em duas versoes: a primeira versao utiliza

apenas vectores da linguagem C tradicional, enquanto a segunda versao substitui todos esses vectores

por vectores da extensao da linguagem.

Os programas que implementam os referidos algoritmos, que em seguida se descrevem, foram

compilados e executados em tres arquitecturas diferentes: um processador Intel x86-64, com frequencia

de 1.80 GHz; um outro processador Intel x86-64, com frequencia de 2.00 GHz, com tecnologia Intel

Turbo Boost [18], e um processador ARMv6, com frequencia de 700 MHz. Calcularam-se os racios

de desempenho entre ambas as versoes de cada algoritmo, de modo a concluir sobre as vantagens

e desvantagens do uso da solucao implementada. Seja n o numero de testes realizados sob cada

conjunto de condicoes, e sejam si e tj dois valores medidos para os tempos de execucao de um

programa, para a versao com e sem recurso aos vectores da extensao da linguagem, respectivamente,

o racio de desempenho entre versoes de cada programa e dado por:

R% = 100

1−

n∑i=1

si

n∑j=1

tj

(5.1)

5.1 Modelos de Teste

Os programas desenvolvidos realizam uma serie de operacoes matematicas sobre vectores multi-

dimensionais e matrizes, nomeadamente o calculo de somas de vectores e produtos de matrizes, bem

como o calculo do determinante de uma matriz quadrada. Cada algoritmo utiliza diferentes estrategias

de acesso as posicoes de cada vector ou matriz, como se vera mais adiante. O Apendice A contem

as listagens do codigo destes programas, implementados na versao estendida da linguagem C. Estas

listagens servem tambem como exemplos de utilizacao da solucao desenvolvida.

5.1.1 Soma de Vectores Tridimensionais

O primeiro algoritmo implementado realiza o calculo da soma de dois vectores tridimensionais.

Implementou-se este algoritmo com recurso a acessos sequenciais as posicoes dos vectores cuja

soma se pretende obter. O codigo elaborado pode ser consultado no Apendice A.1. O programa

realiza acessos sequenciais a posicoes consecutivas dos vectores que se pretendem somar, de modo

a conseguir-se o vector que constitui o resultado da operacao.

Aplicou-se este algoritmo a vectores tridimensionais, preenchidos com valores aleatorios do tipo

int, e com dimensoes de 25x50x75, 40x60x80 e 100x90x80 posicoes. O programa foi elaborado

em duas versoes. A primeira versao, que constitui a Listagem A.1, recorre apenas a vectores da

49

Page 70: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tabela 5.1: Desempenho da soma de vectores num processador Intel x86-64 a 1.80 GHz.

Dimensoes 20x50x75 40x60x80 100x90x80Versao Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,042 0,022 0,103 0,041 0,408 0,149D. Padrao 0,000 0,000 0,000 0,000 0,002 0,000Racio (%) -90,000 -151,220 -173,691

Tabela 5.2: Desempenho da soma de vectores num processador Intel x86-64 a 2.00 GHz.

Dimensoes 20x50x75 40x60x80 100x90x80Versao Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,013 0,010 0,026 0,018 0,081 0,050D. Padrao 0,002 0,003 0,004 0,005 0,013 0,010Racio (%) -33,673 -43,716 -61,800

extensao desenvolvida, recorrendo a outra versao apenas a vectores tradicionais da linguagem C, em

substituicao dos mesmos. Realizaram-se dez medicoes dos tempos de execucao, em segundos, de

cada versao do programa, quando executado sobre cada uma das arquitecturas de processador ja

referidas. Posteriormente, calcularam-se as medias dos tempos medidos e o racio de desempenho em

cada arquitectura.

Os resultados obtidos apresentam-se nas Tabelas 5.1, 5.2 e 5.3. Os tempos medidos nao con-

templam a execucao do codigo em comentario na Listagem A.1, o qual apenas e responsavel por

apresentar o resultado da operacao, como saıda do programa.

5.1.2 Produto de Matrizes Quadradas

O segundo algoritmo implementado consiste no calculo do produto de duas matrizes quadradas.

Esta operacao envolve acessos sequenciais as posicoes de cada linha da primeira matriz, e de cada

coluna da segunda matriz. O codigo de implementacao deste algoritmo pode ser consultado no Apendi-

ce A.2.

O algoritmo foi aplicado a tres pares de matrizes quadradas, de dimensoes 100x100, 250x250 e

500x500. Aplicou-se um tratamento estatıstico semelhante ao processo descrito na subseccao anterior.

O programa foi elaborado em duas versoes, uma das quais apenas utiliza vectores da extensao da

linguagem, recorrendo a outra versao apenas a vectores tradicionais. Executou-se entao cada versao

do programa sobre cada uma das arquitecturas de processador ja referidas.

Realizaram-se dez medicoes de tempos de execucao por cada conjunto de condicoes de teste,

apos as quais se calcularam as medias de tempos de execucao e racios de desempenho entre versoes

correspondentes do programa.

Tambem neste caso se optou por colocar em comentario o codigo responsavel pela apresentacao do

resultado da operacao. Por este motivo, a sua execucao nao e contemplada nos tempos de execucao

50

Page 71: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tabela 5.3: Desempenho da soma de vectores num processador ARMv6 a 700 MHz.

Dimensoes 20x50x75 40x60x80 100x90x80Versao Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,170 0,077 0,339 0,138 1,223 0,513D. Padrao 0,001 0,001 0,001 0,000 0,005 0,001Racio (%) -121,802 -144,902 -138,262

Tabela 5.4: Desempenho do produto de matrizes num processador Intel x86-64 a 1.80 GHz.

Dimensoes 100x100 250x250 500x500Versao Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,043 0,046 0,660 0,932 6,784 8,700D. Padrao 0,000 0,000 0,008 0,002 0,003 0,005Racio (%) 6,725 29,198 22,023

medidos, que podem ser consultados no Apendice B. Os valores resultantes apresentam-se nas Tabe-

las 5.4, 5.5 e 5.6.

5.1.3 Determinante: Formula de Leibniz

Implementou-se o calculo do determinante de uma matriz atraves da aplicacao da Formula de Leib-

niz. O codigo do programa em questao, com recurso a vectores da extensao da linguagem, bem como

uma breve explicacao do algoritmo, podem ser consultados no Apendice A.3. Este programa, em cada

iteracao a excepcao da primeira, realiza acessos a posicoes nao contıguas da matriz cujo determinante

se pretende calcular.

Aplicou-se o algoritmo a matrizes quadradas de valores aleatorios do tipo double, de dimensoes

9x9, 10x10, 11x11 e 12x12. De forma semelhante aos algoritmos anteriormente referidos, alem da

versao listada no Apendice A, foi tambem elaborada uma versao que substitui os vectores da extensao

por vectores tradicionais da linguagem C.

O programa foi compilado e executado sobre as arquitecturas de processador ja referidas. Realizou-

se cada teste um total de dez vezes, recolhendo-se os tempos de execucao de cada teste, em segun-

dos, que se apresentam no Apendice B. Excepcionalmente, no caso da arquitectura ARMv6, nao se

realizou o tratamento estatıstico para o calculo do determinante da matriz de 12x12 posicoes. Neste

caso, verificou-se que cada execucao requeria mais de 10 minutos para concluir, o que inviabilizou a

realizacao de medicoes.

Apos os testes, calculou-se a media de cada conjunto de dez medicoes e, por fim, o racio entre a

media dos tempos de execucao do programa que utiliza os vectores da extensao e a media dos tempos

de execucao do programa correspondente, que apenas utiliza vectores tradicionais. Os resultados dos

calculos referidos, para cada arquitectura de processador, apresentam-se nas Tabelas 5.7, 5.8 e 5.9.

51

Page 72: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tabela 5.5: Desempenho do produto de matrizes num processador Intel x86-64 a 2.00 GHz.

Dimensoes 100x100 250x250 500x500Versao Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,017 0,020 0,189 0,174 1,023 1,115D. Padrao 0,002 0,004 0,014 0,032 0,019 0,035Racio (%) 15,764 -8,913 8,293

Tabela 5.6: Desempenho do produto de matrizes num processador ARMv6 a 700 MHz.

Dimensoes 100x100 250x250 500x500Versao Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,150 0,136 2,511 2,324 28,988 28,498D. Padrao 0,001 0,001 0,007 0,008 0,024 0,197Racio (%) -10,677 -8,041 -1,720

5.2 Discussao dos Resultados

A observacao dos resultados obtidos torna evidente que, alem da diferenca de arquitecturas de pro-

cessador, como referido na Seccao 3.3, tambem o funcionamento de cada algoritmo implementado tem

influencia sobre o desempenho dos vectores da extensao desenvolvida, face aos vectores tradicionais.

Observando, em primeiro lugar, os resultados presentes nas Tabelas 5.1 e 5.2, verifica-se uma

drastica quebra de desempenho quando se utilizam os vectores da extensao da linguagem. Este

fenomeno podera ser explicado pela implementacao das instrucoes de carregamento de valores, nos

processadores em teste, de acordo com o princıpio da localidade espacial [19]. Segundo este princıpio,

apos um acesso a uma posicao de memoria no espaco de enderecamento de um programa, a proba-

bilidade de a ele se seguirem acessos a posicoes proximas da mesma e elevada. Por este motivo, a

realizacao de uma operacao de carregamento de um endereco na memoria principal de um sistema,

e consequente colocacao do valor carregado na memoria cache do processador, consiste realmente

no carregamento de uma gama de enderecos, em que se inclui o endereco pretendido. Esta pratica

permite minimizar o numero de falhas de cache ao longo da execucao de um programa, tornando mais

rapidas as operacoes de carregamento de enderecos consecutivos [19].

A optimizacao referida tem um notavel efeito no desempenho dos vectores tradicionais da lingua-

gem C, quando aplicados ao algoritmo de soma de vectores. Neste caso, o desempenho dos vecto-

res da extensao da linguagem e prejudicado pela latencia introduzida pelas operacoes de calculo de

cada deslocamento utilizado para indexar os vectores. O impacto desta latencia, como seria esperado,

revela-se ainda maior quando o algoritmo e executado sobre a arquitectura ARMv6, como se observa

na Tabela 5.3. Como ja foi referido, a latencia introduzida pelas operacoes de multiplicacao, neste tipo

de arquitectura, e superior a latencia das mesmas em arquitecturas Intel, o que estara na origem da

diferenca entre os racios de desempenho presentes na tabela em questao, face as anteriores.

As Tabelas 5.4, 5.5 e 5.6, referentes ao algoritmo de calculo do produto de matrizes, revelam racios

52

Page 73: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tabela 5.7: Desempenho da formula de Leibniz num processador Intel x86-64 a 1.80 GHz.

Dimensoes 9x9 10x10 11x11 12x12Versao Ext. Trad. Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,109 0,113 1,186 1,226 14,021 14,495 174,244 180,330D. Padrao 0,000 0,000 0,001 0,002 0,003 0,008 0,034 0,022Racio (%) 3,540 3,279 3,270 3,375

Tabela 5.8: Desempenho da formula de Leibniz num processador Intel x86-64 a 2.00 GHz.

Dimensoes 9x9 10x10 11x11 12x12Versao Ext. Trad. Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,036 0,051 0,400 0,427 4,045 4,294 50,090 51,712D. Padrao 0,008 0,012 0,023 0,037 0,058 0,079 0,637 0,267Racio (%) 30,469 6,367 5,803 3,135

de desempenho com valores mais heterogeneos que os anteriores, e com maiores oscilacoes em torno

de zero. Estas oscilacoes sao particularmente visıveis na Tabela 5.5. Porem, e tambem nesta tabela

que se verificam os maiores valores de desvio padrao, relativamente a media de tempos obtida. Pode

notar-se que, quer no teste com matrizes de 100x100 posicoes, quer no teste com 250x250 posicoes, o

valor do desvio padrao corresponde a cerca de 10% da media obtida, no caso dos vectores da extensao

da linguagem, e cerca de 20%, no caso dos vectores tradicionais. Tais oscilacoes terao sido provocadas

pela presenca da tecnologia Intel Turbo Boost nesta arquitectura de CPU em particular. Esta tecnologia

aumenta e reduz dinamicamente a velocidade de relogio do processador, consoante a carga a que o

mesmo esta sujeito em cada momento [18, 20]. Por este motivo, os dados obtidos a partir dos testes

realizados sobre esta arquitectura terao sido influenciados por variacoes dinamicas da velocidade de

relogio do processador, uma vez que esta tecnologia podera ou nao ter sido activada durante algumas

das medicoes. A semelhanca da Tabela 5.5, tambem nas Tabelas 5.2 e 5.8 se podem notar elevados

valores de desvio padrao, ocorrencia que torna esta arquitectura menos fiavel que as restantes para a

extraccao de conclusoes.

Comparando, no entanto, as Tabelas 5.4 e 5.6, verifica-se que, no que toca ao algoritmo de multiplica-

cao de matrizes, a necessidade de carregamento de valores da memoria principal e suficiente para que,

na arquitectura Intel, seja mais vantajosa a alternativa de calculo de deslocamentos. Contrariamente a

soma de vectores, este algoritmo realiza sempre indexacoes de posicoes nao consecutivas de uma das

matrizes, provocando um numero superior de falhas de cache em relacao ao algoritmo de soma. Na

arquitectura ARMv6, por outro lado, a latencia introduzida pelos calculos de deslocamentos tem ainda

um impacto demasiado elevado nos tempos de execucao.

Por fim, a observacao das Tabelas 5.7, 5.8 e 5.9 revela que, contrariamente aos outros algoritmos

testados, o calculo do determinante de uma matriz segundo a formula de Leibniz apresenta apenas

racios de desempenho positivos. O elevado numero de falhas de cache originado pela execucao deste

53

Page 74: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tabela 5.9: Desempenho da formula de Leibniz num processador ARMv6 a 700 MHz.

Dimensoes 9x9 10x10 11x11Versao Ext. Trad. Ext. Trad. Ext. Trad.

Media (s) 0,455 0,470 4,812 4,858 56,653 57,289D. Padrao 0,001 0,028 0,001 0,001 0,003 0,008Racio (%) 3,151 0,955 1,111

algoritmo revela mais vantajosa a utilizacao dos vectores da extensao desenvolvida, ainda que os racios

de desempenho, na sua maioria, nao sejam muito superiores a 3%. Como seria esperado, a arquitec-

tura ARMv6 e a que apresenta valores mais baixos, devido a latencia introduzida pelos calculos dos

deslocamentos dos vectores da extensao da linguagem.

54

Page 75: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

6Conclusao

Conteudo

6.1 Conclusoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.2 Limitacoes e Trabalho Futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

55

Page 76: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

56

Page 77: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

6.1 Conclusoes

Foi proposta uma solucao para a necessidade de combinar mais do que uma linguagem de progra-

macao quando se pretende, num mesmo programa, utilizar vectores com diferentes modalidades de

acesso e diferentes organizacoes em memoria. Foram analisadas as vantagens e desvantagens do uso

de vectores nas linguagens C e Fortran, e descreveu-se o funcionamento tradicional de uma ferramenta

de compilacao, essencial ao desenvolvimento da solucao proposta: uma extensao da linguagem C com

integracao de vectores com o comportamento daqueles que a linguagem Fortran fornece.

Descreveu-se a arquitectura da solucao proposta, referindo-se quais as regras gramaticais propos-

tas para a extensao da linguagem C, quais as principais verificacoes semanticas que sera necessario

realizar pelo compilador, bem como quais as instrucoes da linguagem C tradicional que deverao estar

associadas as novas instrucoes da linguagem estendida.

De seguida, exemplificou-se a utilizacao da solucao, referindo-se as principais diferencas observa-

veis no codigo assembly gerado para as operacoes de indexacao de cada tipo de vectores. Com

base nessas diferencas, fundamentou-se a dependencia do desempenho da solucao nas condicoes de

hardware disponıveis para a execucao dos programas desenvolvidos.

A realizacao da solucao consistiu na construcao de cadeias de caracteres que constituem o codigo

a gerar como saıda da solucao desenvolvida. O texto construıdo e identico ao texto de entrada, com

excepcao das alteracoes resultantes do processamento de operacoes com vectores que utilizem a

sintaxe acrescentada a gramatica da linguagem linguagem. Entre as operacoes a destacar incluem-se

a declaracao, indexacao e passagem de vectores como argumentos de funcoes. Tambem e permitido

o uso da operacao de type cast sobre um ponteiro, para que o conteudo do endereco de memoria

indicado pelo mesmo seja tratado como um vector da extensao desenvolvida.

A avaliacao comparativa do desempenho dos dois tipos de vectores revelou que a decisao acerca

de qual deve ser utilizado no desenvolvimento de um programa nao deve depender apenas do tipo

de arquitectura de processador utilizado, mas tambem do funcionamento do algoritmo implementado.

Quanto menor a latencia introduzida pelas operacoes de multiplicacao na arquitectura responsavel

pela execucao do programa, e quanto maior o numero de falhas de cache que a execucao provoca,

melhor sera o desempenho dos vectores da extensao desenvolvida, face aos vectores tradicionais da

linguagem C.

6.2 Limitacoes e Trabalho Futuro

Apesar da funcionalidade desenvolvida no contexto deste trabalho, a solucao nao se encontra com-

pleta, pois existem operacoes sintactica e semanticamente validas na modalidade tradicional de vec-

tores que nao sao suportadas pelos vectores da extensao desenvolvida. Operacoes como a definicao

57

Page 78: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

de estruturas de dados contendo vectores da extensao como membros, ou a declaracao e indexacao

de vectores de ponteiros para funcoes, sao exemplos de funcionalidade que permanece por realizar.

Tambem nao e suportado o processamento de ficheiros de cabecalho e bibliotecas da linguagem for-

necidas pelo compilador de codigo C tradicional.

Com vista a melhorar a usabilidade da solucao, a mesma podera ainda ser incorporada numa ferra-

menta unica, que combine a execucao da aplicacao desenvolvida com a execucao de um compilador

da linguagem C tradicional. Esta ferramenta podera tambem permitir a activacao ou desactivacao do

uso da semantica dos vectores da extensao da linguagem, visto ter-se comprovado que a mesma nem

sempre e vantajosa. Para o efeito, poder-se-a utilizar um parametro (flag) de execucao do compilador,

que possibilite, em tempo de compilacao, a conversao de todos vectores da extensao da linguagem em

vectores tradicionais. Desta forma, e possıvel ignorar por completo a sintaxe e semantica da extensao

da linguagem, sem a necessidade de alteracao do codigo dos programas a compilar. A conversao in-

versa, porem, nao e possıvel, devido as limitacoes ja descritas nesta seccao, bem como as restricoes

impostas pela nova semantica de vectores que nao podem ser replicadas com os vectores tradicionais,

como a operacao de type cast.

Relativamente a possibilidades de expansao do estudo realizado, ficou por explorar o impacto de

diversas optimizacoes de compilacao de programas na linguagem C, das quais sao exemplos a reducao

de forca de operacoes (strength reduction), referida na Seccao 2.7, ou a regra de strict aliasing, que

possibilita ganhos de desempenho num programa ao impedir a sobreposicao de ponteiros de tipos

diferentes.

No que toca a trabalhos futuros de investigacao, podera ser pertinente o estudo da viabilidade e

desenvolvimento de uma extensao semelhante a que se desenvolveu, aplicada a outras linguagens de

programacao, como a linguagem C++.

58

Page 79: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Bibliografia

[1] P. V. D. Linden, Expert C Programming: Deep C Secrets. Prentice Hall Press, 1994.

[2] B. W. Kernighan and D. M. Ritchie, The C Programming Language, 2nd ed. Upper Saddle River,

NJ, USA: Prentice Hall Press, 1988, vol. 78.

[3] A. S. Tanenbaum, Modern Operating Systems, 2nd ed. Upper Saddle River, NJ, USA: Prentice

Hall Press, 2001.

[4] D. Graves and C. Hogue, Fortran 77 Language Reference Manual, 1994.

[5] J. W. Backus and W. P. Heising, “Fortran,” IEEE Transactions on Electronic Computers, vol. EC-13,

1964.

[6] ANSI, “USA Standard FORTRAN (USAS X3.9-1966),” 1966.

[7] J. C. Adams, W. S. Brainerd, R. a. Hendrickson, R. E. Maine, and J. T. Martin, The Fortran 2003

Handbook, 2008.

[8] P. Kleinrubatscher, A. Kriegshaber, R. Zochling, and R. Gluck, “Fortran Program Specialization,”

ACM SIGPLAN Notices, vol. 30, 1995.

[9] R. W. Numrich and J. Reid, “Co-array Fortran for Parallel Programming,” ACM SIGPLAN Fortran

Forum, vol. 17, no. 2, 1998.

[10] A. V. Aho, M. S. Lam, R. Sethi, and J. D. Ullman, Compilers: Principles, Techniques, and Tools,

2nd ed., 2006.

[11] J. Levine, T. Mason, and D. Brown, Lex & Yacc, 2nd ed. O’Reilly, 1992.

[12] S. McConnell, Code Complete, 2nd ed. Redmond, WA, USA: Dreamtech Press, 2004.

[13] T. A. Davis and K. Sigmon, MATLAB Primer, 7th ed. Boca Raton, FL, USA: CRC Press, Inc., 2005.

[14] L. de Rose and D. Padua, “Techniques for the translation of MATLAB programs into Fortran 90,”

ACM Transactions on Programming Languages and Systems, vol. 21, pp. 286–323, 1999.

59

Page 80: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

[15] J. W. Eaton, GNU Octave, 2007, vol. 103.

[16] J. S. Hansen, GNU Octave Beginner’s Guide, 2011.

[17] T. J. Pennello and F. DeRemer, “Efficient Computation of LALR(1) Look-ahead Sets,” SIGPLAN

Not., vol. 39, no. 4, pp. 14–27, 2004.

[18] J. Casazza, “Intel® Turbo Boost Technology in Intel® Core™ Microarchitecture (Nehalem) Based

Processors,” White paper, Intel Corp, no. November, 2008.

[19] D. A. Patterson and J. L. Hennessy, Computer Organization and Design: The Hardware/Software

Interface, 2009, vol. 4th, no. 0.

[20] J. Charles, P. Jassi, A. Narayan, A. Sadat, and A. Fedorova, “Evaluation of the Intel Core i7 Turbo

Boost Feature,” Proceedings of the 2009 IEEE International Symposium on Workload Characteri-

zation, IISWC 2009, pp. 188–197, 2009.

60

Page 81: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

ACodigo de Avaliacao

Apresentam-se em seguida as listagens de codigo dos programas utilizados para testar a solucao

desenvolvida. Cada listagem e acompanhada por uma breve descricao do funcionamento do algoritmo.

A.1 Soma de Vectores Tridimensionais

A Listagem A.1 apresenta o codigo do programa implementado para o calculo da soma de dois

vectores de tres dimensoes. Os vectores sao declarados nas linhas 20 e 21, e preenchidos com valores

aleatorios nas linhas 24 a 31. A funcao sum, definida nas linhas 10 a 16, indexa sequencialmente cada

posicao dos vectores A e B, recebidos como argumentos. Em cada posicao do vector C, guarda-se o

resultado da soma dos valores guardados nas correspondentes posicoes dos vectores A e B.

61

Page 82: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Listagem A.1: Soma de dois vectores tridimensionais.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 #define X 25

5 #define Y 50

6 #define Z 75

7

8 int C[X; Y; Z];

9

10 void sum(int A[X; Y; Z], int B[X; Y; Z]) {

11 int i, j, k;

12 for(i = 0; i < X; ++i)

13 for(j = 0; j < Y; ++j)

14 for(k = 0; k < Z; ++k)

15 C[i; j; k] = A[i; j; k] + B[i; j; k];

16 }

17

18 int main() {

19 int i, j, k;

20 int A[X; Y; Z];

21 int B[X; Y; Z];

22

23 srand(64777);

24 for(i = 0; i < X; ++i) {

25 for(j = 0; j < Y; ++j) {

26 for(k = 0; k < Z; ++k) {

27 A[i; j; k] = rand();

28 B[i; j; k] = rand();

29 }

30 }

31 }

32

33 sum(A, B);

34 /*

35 printf("==========\n");

36 for(i = 0; i < X; ++i) {

37 for(j = 0; j < Y; ++j) {

62

Page 83: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

38 printf("|\t");

39 for(k = 0; k < Z; ++k)

40 printf("%d\t", C[i; j; k]);

41 printf("|\n");

42 }

43 printf("\n==========\n\n");

44 }

45 */

46 return 0;

47 }

A.2 Produto de Matrizes Quadradas

O codigo do programa de calculo do produto de duas matrizes apresenta-se na Listagem A.2. Este

programa declara e inicializa, com valores aleatorios, duas matrizes quadradas, A e B, cada uma com

o mesmo numero de linhas e colunas. O resultado do produto e guardado numa terceira matriz, C.

Para determinar o valor de cada posicao da matriz C, a funcao multiply, definida nas linhas 8 a 14,

multiplica todos os valores da linha correspondente na matriz A, incrementando o ındice da coluna, pelos

respectivos valores da coluna correspondente na matriz B, incrementando ındice da linha. Cada um

destes produtos constitui uma parcela do valor que devera ocupar a posicao da matriz C correspondente

aos ındices fixados nas matrizes A e B.

Listagem A.2: Produto de duas matrizes quadradas.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 #define N 100

5

6 int C[N; N];

7

8 void multiply(int A[N;], int B[N;]) {

9 int i, j, k;

10 for(i = 0; i < N; ++i)

11 for(j = 0; j < N; ++j)

12 for(k = 0; k < N; ++k)

13 C[i; j] += A[i; k] * B[k; j];

63

Page 84: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

14 }

15

16 int main() {

17 int i, j;

18 int A[N; N];

19 int B[N; N];

20

21 srand(64777);

22 for(i = 0; i < N; ++i) {

23 for(j = 0; j < N; ++j) {

24 A[i; j] = rand();

25 B[i; j] = rand();

26 }

27 }

28

29 multiply(A, B);

30 /*

31 for(i = 0; i < N; ++i) {

32 printf("|\t");

33 for(j = 0; j < N; ++j)

34 printf("%d\t", C[i; j]);

35 printf("|\n");

36 }

37 */

38 return 0;

39 }

A.3 Determinante: Formula de Leibniz

O algoritmo implementado para o calculo do determinante de uma matriz recorre a aplicacao da

formula de Leibniz. O algoritmo itera sobre as posicoes da matriz, percorrendo os ındices das linhas de

forma crescente e sucessiva. Os ındices das colunas variam de acordo com permutacoes de um vector

de ındices, inicialmente contendo uma sequencia tambem crescente e sucessiva.

No codigo da Listagem A.3, o referido vector e declarado e inicializado nas linhas 40 a 42. O mesmo

e passado como argumento da funcao leibniz, definida nas linhas 22 a 37. Sao entao criadas tantas

novas sequencias de ındices quantas as possıveis permutacoes da sequencia original. Para o efeito,

em cada chamada recursiva da funcao leibniz, determinam-se todas as permutacoes possıveis de

64

Page 85: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

um elemento do vector com os elementos em posicoes seguintes ao mesmo (linhas 31 a 35). Cada

permutacao origina uma troca de sinal do argumento signature, que pode ter o valor 1 ou -1. Tambem

se realiza uma chamada recursiva que preserva o vector de ındices, sem realizar uma permutacao, caso

em que o argumento signature nao troca de sinal. O ciclo presente nas linhas 31 a 35 e responsavel

por ramificar a execucao do programa, de modo a conseguir um caminho de execucao para cada

permutacao dos elementos da sequencia de ındices mencionada.

No caso de paragem da recursao, na linha 25, o vector contem uma sequencia de ındices ja proces-

sada, e e entao utilizado para indexar a matriz cujo determinante se pretende calcular. Cada acesso

a matriz realiza-se com um ındice de linha incrementado unitariamente, e com o ındice de coluna indi-

cado pelo vector. Acumula-se entao o produto de todos os elementos acedidos numa variavel auxiliar.

O resultado deste produto e multiplicado pelo valor do argumento signature, que sera igual a 1 ou -1,

consoante tenha sido realizado um numero par ou ımpar de permutacoes, respectivamente. Este valor

corresponde a uma parcela do determinante da matriz, o qual, apos a chamada da funcao leibniz, na

linha 44, fica guardado na variavel global det.

Listagem A.3: Formula de Leibniz para o determinante de uma matriz.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 #define N 10

5

6 double A[N;N], det = 0;

7

8 void fill matrix(unsigned int seed) {

9 int i, j;

10 srand(seed);

11 for(i = 0; i < N; ++i)

12 for(j = 0; j < N; ++j)

13 A[i;j] = rand();

14 }

15

16 void swap(int *first, int *second) {

17 int temp = *first;

18 *first = *second;

19 *second = temp;

20 }

65

Page 86: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

21

22 void leibniz(int *array, int current, int size, int signature) {

23 int a;

24 double temp = 1;

25 if (current == size - 1) {

26 for (a = 0; a < size; ++a)

27 temp *= A[array[a];a];

28 det += signature * temp;

29 }

30 else {

31 for (a = current; a < size; ++a) {

32 swap(array + current, array + a);

33 leibniz(array, current + 1, size, current == a ? signature : -signature);

34 swap(array + current, array + a);

35 }

36 }

37 }

38

39 int main() {

40 int a, indices[N];

41 for (a = 0; a < N; ++a)

42 indices[a] = a;

43 fill matrix(64777);

44 leibniz(indices, 0, N, 1);

45 printf("det(A) = %.1f\n", det);

46 return 0;

47 }

66

Page 87: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

BTempos de Execucao

Em seguida, apresentam-se os tempos, em segundos, medidos para cada execucao dos programas

de teste da solucao desenvolvida, referidos na Seccao 5.1. Na mesma seccao, apresentam-se os

resultados da analise estatıstica destes dados. O codigo de cada programa pode ser consultado no

Apendice A.

67

Page 88: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tabela B.1: Execucao da soma de vectores num processador Intel x86-64 a 1.80 GHz.

Condicoes de Teste100x100 250x250 500x500

Medicoes Ext. Trad. Ext. Trad. Ext. Trad.1 0,042 0,022 0,103 0,041 0,408 0,1492 0,042 0,022 0,103 0,041 0,412 0,1493 0,042 0,022 0,103 0,041 0,407 0,1494 0,042 0,022 0,103 0,041 0,407 0,1495 0,041 0,022 0,103 0,041 0,406 0,1496 0,042 0,022 0,103 0,041 0,409 0,1497 0,042 0,022 0,103 0,041 0,407 0,1498 0,042 0,022 0,103 0,041 0,408 0,1499 0,042 0,022 0,103 0,041 0,406 0,149

10 0,041 0,022 0,103 0,041 0,408 0,149Media 0,042 0,022 0,103 0,041 0,408 0,149

D. Padrao 0,000 0,000 0,000 0,000 0,002 0,000

Tabela B.2: Execucao da soma de vectores num processador Intel x86-64 a 2.00 GHz.

Condicoes de Teste100x100 250x250 500x500

Medicoes Ext. Trad. Ext. Trad. Ext. Trad.1 0,012 0,018 0,024 0,031 0,070 0,0512 0,017 0,009 0,032 0,018 0,075 0,0623 0,013 0,008 0,036 0,014 0,088 0,0404 0,016 0,009 0,025 0,019 0,109 0,0675 0,012 0,009 0,025 0,021 0,089 0,0616 0,012 0,009 0,024 0,014 0,089 0,0427 0,015 0,012 0,024 0,014 0,073 0,0548 0,011 0,008 0,025 0,014 0,079 0,0409 0,012 0,008 0,021 0,017 0,069 0,039

10 0,011 0,008 0,027 0,021 0,068 0,044Media 0,013 0,010 0,026 0,018 0,081 0,050

D. Padrao 0,002 0,003 0,004 0,005 0,013 0,010

Tabela B.3: Execucao da soma de vectores num processador ARMv6 a 700 MHz.

Condicoes de Teste100x100 250x250 500x500

Medicoes Ext. Trad. Ext. Trad. Ext. Trad.1 0,169 0,077 0,339 0,139 1,234 0,5152 0,169 0,077 0,337 0,138 1,220 0,5143 0,172 0,078 0,339 0,138 1,221 0,5124 0,171 0,077 0,340 0,138 1,222 0,5155 0,170 0,076 0,340 0,138 1,228 0,5126 0,169 0,076 0,340 0,138 1,225 0,5117 0,171 0,077 0,337 0,139 1,222 0,5138 0,169 0,076 0,337 0,138 1,220 0,5149 0,169 0,076 0,338 0,138 1,219 0,514

10 0,170 0,076 0,340 0,139 1,219 0,513Media 0,170 0,077 0,339 0,138 1,223 0,513

D. Padrao 0,001 0,001 0,001 0,000 0,005 0,001

68

Page 89: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tabela B.4: Execucao do produto de matrizes num processador Intel x86-64 a 1.80 GHz.

Condicoes de Teste100x100 250x250 500x500

Medicoes Ext. Trad. Ext. Trad. Ext. Trad.1 0,043 0,046 0,656 0,932 6,785 8,6972 0,043 0,046 0,657 0,935 6,780 8,6983 0,043 0,046 0,654 0,930 6,783 8,6984 0,043 0,046 0,655 0,935 6,780 8,7135 0,043 0,046 0,665 0,931 6,786 8,7016 0,043 0,046 0,652 0,931 6,783 8,6947 0,043 0,046 0,654 0,932 6,790 8,7018 0,043 0,046 0,674 0,932 6,781 8,6979 0,043 0,047 0,658 0,931 6,787 8,697

10 0,043 0,046 0,673 0,930 6,783 8,701Media 0,043 0,046 0,660 0,932 6,784 8,700

D. Padrao 0,000 0,000 0,008 0,002 0,003 0,005

Tabela B.5: Execucao do produto de matrizes num processador Intel x86-64 a 2.00 GHz.

Condicoes de Teste100x100 250x250 500x500

Medicoes Ext. Trad. Ext. Trad. Ext. Trad.1 0,018 0,024 0,175 0,148 1,044 1,1502 0,018 0,023 0,190 0,116 1,029 1,1243 0,016 0,022 0,180 0,129 1,025 1,1274 0,022 0,023 0,211 0,177 1,001 1,0945 0,017 0,019 0,200 0,186 0,997 1,1076 0,017 0,022 0,172 0,182 1,053 1,1877 0,014 0,018 0,191 0,207 1,038 1,1148 0,015 0,015 0,190 0,186 1,008 1,0819 0,017 0,014 0,211 0,203 1,010 1,064

10 0,017 0,023 0,174 0,205 1,024 1,106Media 0,017 0,020 0,189 0,174 1,023 1,115

D. Padrao 0,002 0,004 0,014 0,032 0,019 0,035

Tabela B.6: Execucao do produto de matrizes num processador ARMv6 a 700 MHz.

Condicoes de Teste100x100 250x250 500x500

Medicoes Ext. Trad. Ext. Trad. Ext. Trad.1 0,151 0,137 2,512 2,315 29,031 28,4022 0,149 0,135 2,498 2,324 28,990 28,3963 0,154 0,135 2,507 2,317 28,995 28,2594 0,150 0,136 2,526 2,310 29,005 28,4175 0,149 0,135 2,514 2,325 28,957 28,3896 0,151 0,137 2,512 2,332 28,986 28,8107 0,150 0,136 2,514 2,330 29,008 28,8298 0,150 0,135 2,507 2,324 28,954 28,3699 0,149 0,136 2,507 2,334 28,972 28,66010 0,150 0,136 2,516 2,333 28,981 28,445

Media 0,150 0,136 2,511 2,324 28,988 28,498D. Padrao 0,001 0,001 0,007 0,008 0,024 0,197

69

Page 90: Vectores de Fortran em C - fenix.tecnico.ulisboa.pt · partilhar a minha experiencia com alguˆ em que, em troca, partilhou a sua.´ Ao meu grande amigo Miguel Coelho, alem da disponibilizac¸´

Tabela B.7: Execucao da formula de Leibniz num processador Intel x86-64 a 1.80 GHz.

Condicoes de Teste9x9 10x10 11x11 12x12

Medicoes Ext. Trad. Ext. Trad. Ext. Trad. Ext. Trad.1 0,109 0,113 1,185 1,225 14,017 14,497 174,257 180,3872 0,109 0,113 1,185 1,230 14,021 14,487 174,217 180,3363 0,109 0,113 1,186 1,227 14,023 14,497 174,197 180,3244 0,109 0,113 1,188 1,225 14,018 14,505 174,240 180,3225 0,109 0,113 1,185 1,226 14,023 14,490 174,252 180,3136 0,109 0,113 1,186 1,226 14,020 14,488 174,219 180,3157 0,109 0,113 1,186 1,225 14,015 14,497 174,319 180,3148 0,109 0,113 1,186 1,226 14,024 14,507 174,269 180,3299 0,109 0,113 1,185 1,225 14,021 14,494 174,241 180,34510 0,109 0,113 1,186 1,225 14,024 14,483 174,226 180,318

Media 0,109 0,113 1,186 1,226 14,021 14,495 174,244 180,330D. Padrao 0,000 0,000 0,001 0,002 0,003 0,008 0,034 0,022

Tabela B.8: Execucao da formula de Leibniz num processador Intel x86-64 a 2.00 GHz.

Condicoes de Teste9x9 10x10 11x11 12x12

Medicoes Ext. Trad. Ext. Trad. Ext. Trad. Ext. Trad.1 0,032 0,040 0,396 0,412 4,080 4,368 49,495 52,2662 0,036 0,036 0,416 0,424 4,000 4,292 50,365 52,0573 0,036 0,036 0,408 0,404 4,084 4,208 50,211 51,6424 0,036 0,060 0,392 0,404 4,068 4,160 50,638 51,3315 0,040 0,060 0,412 0,436 4,108 4,232 51,526 51,7106 0,056 0,060 0,428 0,452 4,124 4,436 49,999 51,5107 0,032 0,060 0,400 0,512 4,032 4,296 49,525 51,6688 0,028 0,036 0,344 0,408 4,016 4,332 49,719 51,7009 0,032 0,064 0,392 0,444 4,008 4,316 49,931 51,569

10 0,028 0,060 0,412 0,376 3,932 4,304 49,493 51,662Media 0,036 0,051 0,400 0,427 4,045 4,294 50,090 51,712

D. Padrao 0,008 0,012 0,023 0,037 0,058 0,079 0,637 0,267

Tabela B.9: Execucao da formula de Leibniz num processador ARMv6 a 700 MHz.

Condicoes de Teste9x9 10x10 11x11

Medicoes Ext. Trad. Ext. Trad. Ext. Trad.1 0,455 0,461 4,812 4,859 56,648 57,2952 0,455 0,550 4,813 4,859 56,651 57,2863 0,455 0,463 4,810 4,858 56,649 57,2864 0,454 0,459 4,812 4,858 56,649 57,2885 0,456 0,462 4,811 4,857 56,652 57,3096 0,456 0,461 4,813 4,859 56,657 57,2847 0,455 0,462 4,813 4,860 56,655 57,2858 0,455 0,459 4,812 4,857 56,654 57,2869 0,454 0,459 4,812 4,858 56,655 57,28910 0,454 0,461 4,812 4,859 56,657 57,286

Media 0,455 0,470 4,812 4,858 56,653 57,289D. Padrao 0,001 0,028 0,001 0,001 0,003 0,008

70