SlideShare ist ein Scribd-Unternehmen logo
1 von 56
Downloaden Sie, um offline zu lesen
`
     ALMA MATER STUDIORUM - UNIVERSITA DI BOLOGNA
                                     `
                           FACOLTA DI INGEGNERIA
                 Corso di Laurea Triennale in Ingegneria Informatica




                  Tesi di Laurea in Fondamenti di Informatica L-B




                        Analisi di prestazione
                       dell’interprete tuProlog
                         su piattaforma Java




Candidato                                                  Relatore
Michele Damian                                             Chiar.mo Prof. Enrico Denti




                           Anno Accademico 2007/08
Indice

Introduzione                                                                                                                 vii

1 Il motore tuProlog                                                                                                          1

2 Benchmarks                                                                      7
  2.1 Profilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
      2.1.1 Il profiler HPROF . . . . . . . . . . . . . . . . . . . . . . . 10
  2.2 Teorie di test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3 Analisi dei tempi di esecuzione                                                                                            13
  3.1 Metodo di profiling . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   13
  3.2 Tempi di esecuzione dei metodi         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
  3.3 Analisi della scalabilit` . . . . .
                              a              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   20
  3.4 Grafo delle chiamate . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   22

4 Analisi dell’utilizzo della memoria                                                                                        25
  4.1 Metodo di profiling . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
  4.2 Allocazione degli oggetti in memoria               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
  4.3 Analisi del garbage collector . . . . .            .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   32
  4.4 Grafo delle allocazioni . . . . . . . .            .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   35

5 Confronto con la versione tuProlog 1.3                                                                                     39

6 Conclusioni                                                                                                                41




                                         i
Elenco delle figure

 1.1   Il pattern state che realizza la macchina a stati finiti . . . . . . . .     3
 1.2   La macchina a stati finiti del motore tuProlog . . . . . . . . . . . .       4

 3.1   Analisi delle chiamate ai metodi pi` utilizzati nell’esecuzione delle
                                             u
       teorie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

 4.1   Analisi delle istanziazioni degli oggetti pi` allocati nell’esecuzione
                                                     u
       delle teorie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37




                                        iii
Elenco delle tabelle

 3.1   Tempi di esecuzione per cento risoluzioni e errore relativo calcolato
       per una singola esecuzione. . . . . . . . . . . . . . . . . . . . . . .     .   15
 3.2   Tempi di lettura ed esecuzione. . . . . . . . . . . . . . . . . . . .       .   16
 3.3   Analisi dei metodi. . . . . . . . . . . . . . . . . . . . . . . . . . .     .   19
 3.4   Analisi dei metodi totale. . . . . . . . . . . . . . . . . . . . . . . .    .   20
 3.5   Analisi della scalabilit` del motore tuProlog. . . . . . . . . . . . .
                               a                                                   .   21
 3.6   Associazione fra il numero identificativo di un nodo nella Figura 3.1
       e il metodo che esso rappresenta. . . . . . . . . . . . . . . . . . .       . 23

 4.1   Analisi degli oggetti utilizzati. . . . . . . . . . . . . . . . . . . . .   . 30
 4.2   Analisi dell’utilizzo della memoria da parte degli oggetti rispetto
       all’obiettivo della teoria. . . . . . . . . . . . . . . . . . . . . . . .   . 31
 4.3   Analisi complessiva degli oggetti utilizzati. . . . . . . . . . . . . .     . 32
 4.4   Analisi del garbage collector. . . . . . . . . . . . . . . . . . . . . .    . 35
 4.5   Associazione fra il numero identificativo di un nodo nella Figura 4.1
       e l’oggetto che esso rappresenta. . . . . . . . . . . . . . . . . . . .     . 36

 5.1   Comparazione dei tempi di esecuzione nelle singole teorie. . . . . . . 40
 5.2   Comparazione dell’allocazione della memoria nelle singole teorie. . . 40




                                         v
Introduzione

    Il motore tuProlog ` un interprete per il linguaggio Prolog, scritto interamente
                        e
in Java e interoperabile con le librerie fornite dalla piattaforma di sviluppo JDK.
Giunto recentemente alla versione 2.1, ha portato con s´ diversi cambiamenti dal
                                                              e
punto di vista strutturale. L’obiettivo del lavoro ` quello di analizzare le pre-
                                                        e
stazioni dell’interprete in modo tale da porre delle basi utili per un suo ulteriore
miglioramento in versioni successive. Alla conclusione, all’eventuale revisore del-
l’interprete, sar` chiaro su quali parti del codice dovr` orientare la sua attenzione
                 a                                        a
per apportare dei miglioramenti. A questo proposito l’analisi viene scomposta in
due sezioni, con lo scopo di mettere in luce l’utilizzo della cpu e l’allocazione della
memoria heap da parte dei metodi e delle classi implementate dal motore. Per
quanto riguarda le prestazioni in termini di velocit`, allo stato attuale, i dati a di-
                                                      a
sposizione si basano unicamente sui tempi di esecuzione di alcune teorie utilizzate
come benchmark per interpreti Prolog e considerate standard per test prestazionali
di questo tipo di motore. A causa della variazione del sistema hardware sul quale
vengono eseguiti i test, queste teorie per` non garantiscono tempi di esecuzione ab-
                                          o
bastanza elevati da poter essere misurati con un apprezzabile errore sulla misura.
Per questo motivo ad esse devono essere aggiunte delle nuove teorie per ottimizzare
il benchmark. Un altro obiettivo che il lavoro si pone ` quello di analizzare come
                                                            e
sono cambiate le prestazioni dell’interprete in seguito al passaggio dalla versione
1 alla versione 2, la quale ha introdotto alcune modifiche a livello architetturale.
In particolare viene presa come riferimento l’ultima release di ognuna delle due
versioni, le quali sono rispettivamente la release 1.3 e 2.1.

    La dissertazione ` strutturata in modo da rendere pi` comprensibile possi-
                       e                                       u
bile il motivo delle scelte fatte durante il progetto. Il Capitolo 1 presenta il motore

                                          vii
tuProlog, spiegando quali sono le caratteristiche principali dell’interprete e facendo
un’analisi di alto livello del suo funzionamento. Nel Capitolo 2 vengono discussi
i motivi che hanno portato alla scelta di HPROF come strumento di profiling,
nonch´ le sue funzionalit` principali. Inoltre vengono presentate le teorie di test
        e                  a
che hanno permesso di ricavare le informazioni utilizzate nell’analisi di tuProlog.
Nei capitoli successivi si entra nella parte centrale del lavoro, esponendo queste
informazioni e analizzando qual ` il loro significato. In particolare, nel Capitolo 3
                                   e
vengono analizzati i tempi di esecuzione, mentre nel Capitolo 4 viene analizzato
l’utilizzo della memoria heap da parte di tuProlog. Nel Capitolo 5 si trova un
confronto fra la pi` recente versione di tuProlog (2.1) e la versione 1.3. Questo
                    u
confronto viene fatto riferendosi ai tempi di esecuzione ed ai dati relativi all’uso
della memoria. Infine, nel Capitolo 6, vengono tratte le conclusioni, esponendo
quali sono le parti del motore che possono essere migliorate.




                                         viii
Capitolo 1

Il motore tuProlog

     L’obiettivo per cui l’interprete tuProlog venne ideato fu quello di poter disporre
di uno strumento in grado di realizzare dei componenti intelligenti da poter utiliz-
zare in un’infrastruttura internet dinamica. La base sulla quale viene costruito ` il
                                                                                    e
linguaggio di programmazione logica dichiarativo Prolog. Sin dal primo interprete,
scritto nel 1972, le implementazioni dei sistemi Prolog si pongono come obiettivo
quello di ottimizzare fattori quali il tempo di esecuzione e l’utilizzo della memoria.
tuProlog, scritto interamente in Java, si discosta da questa tendenza, introducendo
nell’architettura dell’interprete i concetti legati alla programmazione orientata agli
oggetti, con lo scopo di poterne sfruttare i vantaggi. Tra questi pregi, apprezzati
quando si deve scrivere codice utilizzabile in infrastrutture intelligenti e sistemi
dinamici, vi sono: la portabilit`, ovvero la facilit` con cui ` possibile distribuire
                                   a                   a        e
l’applicazione, legata solamente alla presenza della piattaforma Java; la riusabi-
lit`, che permette il riutilizzo di componenti in diversi sistemi; la modularit`, che
   a                                                                             a
determina anche la leggerezza del core. Queste nozioni, ben note nell’ingegneria
del software, vengono realizzate implementando i pattern descritti in seguito.

    In primo luogo viene considerata la riusabilit` e la modularit` dell’architet-
                                                  a                 a
tura del motore tuProlog. Esse vengono rese possibili grazie alla separazione delle
responsabilit` del sistema. Ogni responsabilit` viene associata ad un singolo ma-
             a                                a
nager il quale controlla parte del motore tuProlog, in modo tale che le librerie e
i predicati primitivi siano indipendenti dal motore e possano essere sostituite o

                                          1
CAPITOLO 1. IL MOTORE TUPROLOG


modificate preservando il funzionamento del sistema. Queste caratteristiche sono
rese possibili grazie al pattern Fa¸ade [2], che riduce anche il numero di oggetti
                                      c
che il cliente deve utilizzare, rendendo il sistema pi` semplice da gestire. Sono
                                                          u
presenti quattro tipi di manager per gestire diversi oggetti: il manager delle li-
brerie, il manager delle primitive, il manager delle teorie e il manager degli stati
della macchina a stati finiti. Il manager delle librerie rende possibile il caricamento
delle librerie di predicati al bisogno, anche a runtime. Questa peculiarit`, oltre
                                                                                a
a rendere estremamente configurabile tuProlog, fa si che il core metta a disposi-
zione funzionalit` essenziali e quindi dia migliori prestazioni in termini di tempi
                   a
di esecuzione e utilizzo della memoria. Tuttavia esistono alcuni predicati che non
sono stati inseriti nelle librerie, ma sono stati definiti nel motore. Essi sono quei
predicati che influenzano il processo di risoluzione, come cut/0, quelli che sono
troppo basilari per essere definiti altrove, come fail/0 e quelli che per ragioni di
efficienza devono essere definiti vicino al core, come ’,’/2. A parte queste eccezioni
tutti gli altri predicati sono contenuti all’interno di librerie, le cui seguenti sono
caricate durante la fase di creazione del motore: la libreria BasicLibrary, la quale
contiene i predicati pi` importanti, escludendo i predicati di I/O; la libreria IO-
                        u
Library che mette a disposizione alcuni dei predicati di input/output standard di
Prolog, come write/1, read/1 e nl/0; la libreria ISOLibrary che definisce predicati
standard ISO non definiti nelle due librerie precedenti; e JavaLibrary che definisce
tutti quei predicati idonei a permettere l’interazione fra Prolog e Java. Tutte le
altre librerie, come quelle definite dall’utente, possono essere caricate runtime. Il
manager delle primitive ha il compito di riconoscere i predicati presenti all’interno
delle teorie da quelli definiti nelle librerie o dall’utente. Questa operazione ` neces-
                                                                                e
saria in quanto i due gruppi di predicati dovranno essere trattati differentemente
durante il processo di risoluzione: i primi dovranno essere eseguiti come metodi
Java ogni qualvolta la risoluzione di una teoria preveda prima la loro risoluzione,
mentre gli altri saranno gestiti dalla macchina a stati finiti del motore tuProlog.
Il parser del motore tuProlog legge la teoria Prolog riconoscendo la corretta sin-
tassi e creando gli oggetti corrispondenti ai termini identificati. A supporto del
parser il manager delle teorie crea il database delle clausole, a cui il motore far`  a
riferimento durante il processo di risoluzione e riconosce le direttive che devono
essere eseguite immediatamente. Per questioni di ottimizzazione il corpo di una

                                          2
Figura 1.1: Il pattern state che realizza la macchina a stati finiti



proposizione viene decomposto in sotto obiettivi non appena essa stessa viene rico-
nosciuta e non durante la fase di risoluzione. La proposizione viene rappresentata
in memoria tramite una struttura dati ad albero in cui ogni foglia rappresenta un
sotto obiettivo.

    Infine il manager del motore si occupa di gestire i motori di risoluzione crean-
do un’istanza della macchina a stati finiti per ogni teoria che debba essere risolta
(situazione che potrebbe presentarsi nel caso le teorie siano innestate l’una nell’al-
tra). Questa macchina, nel quale ogni stato rappresenta un passo nella risoluzione
della teoria, ` di fondamentale importanza in quanto realizza il motore di riso-
               e
luzione delle teorie. Inoltre, il manager del motore permette di disaccoppiare il
motore di risoluzione tuProlog dal resto dell’architettura favorendo l’estensibilit`a
della macchina a stati finiti, a cui diventa possibile aggiungere nuovi stati. Per
realizzare tutto ci` viene usato il pattern State [2] che permette di istanziare og-
                   o
getti il cui comportamento dipende dallo stato interno. La classe Engine mantiene
al suo interno sia lo stato attuale della macchina a stati finiti sia lo stato suc-
cessivo al quale deve transitare, mentre gli stati vengono realizzati derivando la
classe astratta State. Pi` dettagliatamente il motore comprende uno stato iniziale
                         u
(Init), quattro stati rappresentanti le attivit` svolte durante il processo di riso-
                                               a
luzione (Goal Selection, Goal Evaluation, Rule Selection e Backtrack) e quattro
stati finali rappresentanti i modi in cui la risoluzione potrebbe terminare (HALT,
TRUE, TRUE CP e FALSE).




                                          3
CAPITOLO 1. IL MOTORE TUPROLOG




            Figura 1.2: La macchina a stati finiti del motore tuProlog


     Lo stato Init ` il punto di partenza e ha il compito di inizializzare il motore
                    e
di risoluzione estraendo gli obiettivi da valutare dalla teoria e creando un ogget-
to che rappresenta il contesto nella quale l’obiettivo verr` valutato. Dopodich´
                                                              a                     e
il controllo verr` passato allo stato Goal Selection il quale seleziona l’obiettivo
                  a
da valutare da una lista di obiettivi. Se questo obiettivo non viene trovato e il
processo di esecuzione ` terminato si possono presentare due casi: se esiste un
                          e
punto di scelta e quindi la teoria pu` avere un’altra soluzione, lo stato finale sar`
                                       o                                            a
TRUE CP, altrimenti lo stato finale sar` TRUE. Se invece esiste un altro obiettivo
                                         a
che pu` essere estratto deve essere valutato nello stato Goal Evaluation, a meno
        o
che esso non rappresenti un numero, in qual caso la risoluzione termina nello stato
FALSE. Se l’obbiettivo valutato nello stato Goal Evaluation rappresenta un pre-
dicato primitivo allora la macchina a stati finiti transita nello stato Goal Selection
o Backtrack, a seconda se la valutazione del predicato abbia avuto esito positivo o
negativo, altrimenti transita nello stato Rule Selection e viene scelta una clausola
compatibile per la risoluzione della teoria. In qualsiasi momento venga raggiunta
una condizione di errore nello stato Goal Evaluation la macchina transita nello
stato HALT e termina l’esecuzione. Nel caso non venga trovata nessuna clausola
dal set di regole compatibili con l’attuale obiettivo allora lo stato successivo sar`
                                                                                    a
quello di Backtrack. Nello stato di Rule Selection viene preparato un nuovo con-
testo di esecuzione, l’obiettivo viene unificato con la testa della clausola, il corpo
della clausola viene aggiunto al risolvente, viene creato un nuovo punto di scelta ed
il sistema transita nello stato di Goal Selection. Infine lo stato di Backtrack ha il

                                         4
compito di trovare una clausola compatibile dal contesto creato nell’ultimo punto
di scelta aperto, se questa non viene trovata il motore termina la sua esecuzione
nello stato FAIL.




                                       5
Capitolo 2


Benchmarks


    La scelta del benchmark ` un passo importante nell’analisi delle prestazioni di
                               e
un software. Le funzionalit` del benchmark, il modo in cui le prestazioni vengono
                             a
da esso misurate e il modo in cui i dati finali vengono rappresentati determinano
quali parti del sistema ` possibile analizzare, come ` possibile analizzarle attraverso
                        e                             e
lo strumento e come i dati possono essere interpretati e rielaborati in modo che essi
abbiano un significato concreto, tale da mettere alla luce le lacune del software esa-
minato. Il capitolo ` diviso in due sezioni. La prima descrive brevemente i possibili
                     e
profiler adatti ad un’analisi di memoria e velocit` di esecuzione di un’applicazione
                                                    a
Java. Vengono poi confrontati i vari strumenti ed esposte le ragioni che hanno por-
tato alla scelta dell’uno anzich´ dell’altro, soffermandosi sulle caratteristiche del
                                  e
profiler HPROF, che fornisce i dati analizzati nei capitoli successivi. La seconda
sezione riguarda invece le teorie di test, essenziali per esaminare il comportamento
del sistema attraverso il profiler. La risoluzione delle clausole di Horn attraverso
l’interprete tuProlog viene infatti eseguita per una teoria ben precisa, in quanto
ogni teoria determina una successione dei cambiamenti di stato della macchina
a stati finiti diverso dalle altre e di conseguenza un diverso comportamento del
motore tuProlog. Quindi, durante la scrittura delle teorie, si considera che esse
devono testare l’interprete in modo tale da poterne analizzare le prestazioni in
tutti i possibili impieghi.

                                          7
CAPITOLO 2. BENCHMARKS


2.1       Profilers
    Il profiler ` essenzialmente uno strumento in grado di misurare le performance
               e
e analizzare il comportamento di un certo software durante la sua esecuzione. Il
modo in cui questo viene attuato ed il modo in cui i dati collezionati vengono
resi disponibili al cliente varia da profiler a profiler. La scelta dello strumento pi` u
adatto allo scopo ` dettata non solo da quali variabili si debbano misurare durante
                    e
il profiling, ma anche dalla qualit` e quantit` delle informazioni che ` possibile
                                      a          a                          e
ricavare analizzando i dati forniti. Ad esempio, la scelta di un profiler in grado
di misurare, o in grado di fornire dati dal quale sia possibile misurare, la memo-
ria allocata da metodi, anche innestati, viene privilegiata rispetto ad un profiler
che fornisce solamente i dati relativi alla memoria allocata durante l’esecuzione
dell’applicazione. La qualit` delle informazioni ricavate pu` anche essere definita
                              a                                o
come la varianza dei dati misurati dallo strumento in esecuzioni diverse della stes-
sa teoria o in esecuzioni della stessa teoria su piattaforme diverse. Maggiore ` lae
varianza, minore sar` la qualit` delle informazioni in possesso. Questo problema `
                       a         a                                                    e
reso evidente dal fatto che i dati ricavati saranno disponibili per future estensioni o
modifiche, cosa difficilmente possibile nel caso queste informazioni non siano para-
gonabili con quelle misurate su altre piattaforme. Sebbene la risoluzione di questo
quesito meriti una discussione a s´ ` possibile ovviare al problema esprimendo i
                                      ee
tempi di esecuzione dei vari metodi1 con un valore relativo al tempo di esecuzione
totale della teoria, anzich´ come valore assoluto. In questo modo si possono avere
                            e
informazioni relative a quanto incide un metodo sul tempo di esecuzione totale e
questo dato rimane coerente fra diverse esecuzioni dell’interprete in diverse piat-
taforme2 .

    Dato per scontato che lo strumento con cui viene fatto il profiling debba essere
in grado di misurare la quantit` di memoria heap allocata e i tempi di esecuzione
                                a

     Si vedr` pi` avanti che viene assunto come ipotesi il fatto che il tempo di esecuzione totale
            au
   1

della teoria sia dato dalla somma del tempo di esecuzione dei singoli metodi e l’ottimizzazione
di uno di essi comporta l’ottimizzazione del tempo di esecuzione totale.
     Non ` escluso che alcuni sistemi operativi, o alcune implementazioni JVM diverse da quella
          e
   2

della Sun Microsystems, presentino ottimizzazioni che potrebbero far variare le velocit` di ese-
                                                                                         a
cuzione relative dei vari metodi. Queste variazioni dovrebbero comunque essere ragionevolmente
piccole.


                                                8
2.1. PROFILERS


di un’applicazione Java, essendo tuProlog scritto interamente in Java, la scelta del
profiler viene fatta in primo luogo fra due categorie: i profiler commerciali e quelli
non commerciali3 . Data la natura accademica della ricerca si opta per un profiler
con licenza di tipo non commerciale. Questa scelta ` dettata dal fatto che utiliz-
                                                        e
zare un software commerciale porrebbe delle barriere economiche ad una futura
prosecuzione dell’analisi svolta. Un altro fattore di interesse nella scelta dello stru-
mento pi` consono `, come detto in precedenza, la possibilit` di misurare i tempi
          u           e                                          a
di esecuzione e la quantit` di memoria allocata dai vari metodi utilizzati durante
                           a
la risoluzione di una teoria. Inoltre, osservando l’architettura della macchina a
stati finiti, si pu` facilmente intuire che alcuni degli stati in cui il sistema transita
                  o
                                                                   `
vengono utilizzati in maniera predominante rispetto ad altri. E quindi opportuno
che la scelta venga indirizzata su un profiler che fornisca anche il numero di chia-
mate ad un metodo, in modo da poter analizzare meglio se il sistema spende un
certo tempo, o una certa quantit` di memoria, perch´ effettua un numero elevato
                                   a                     e
di chiamate a questo o perch´ esso ` computazionalmente complesso.
                               e      e

    Una buona parte dei profiler con le caratteristiche indicate ` basata sull’in-
                                                                      e
terfaccia JVM TI (acronimo di Java Virtual Machine Tool Interface) fornita nella
piattaforma J2SE della Sun Microsystems a partire dalla versione 1.5. Questa
interfaccia provvede un accesso allo stato della JVM da parte di altri strumenti
attraverso delle API. All’atto dell’inizializzazione della VM una libreria, scritta in
C o C++, viene caricata. Questa pu` invocare chiamate o registrarsi ad eventi,
                                        o
secondo quanto descritto dall’interfaccia, allo scopo di interrogare la VM riguardo
al suo stato. Nei seguenti capitoli i dati sono tutti ricavati dalla libreria HPROF.
Questo agente, a differenza degli altri strumenti a disposizione, presenta i risul-
tati in maniera piuttosto grezza, senza che vengano elaborati o formattati. Quel
che pu` sembrare un difetto, o una mancanza di qualit`, ` in realt` un pregio.
        o                                                   ae            a
Gli altri profiler infatti, presentando un output pi` o meno elaborato, tendono a
                                                      u
mettere in risalto un aspetto del sistema anzich´ un altro, perdendo informazione.
                                                  e
Con HPROF ` possibile invece elaborare i dati grezzi, in modo tale da mettere in
               e
risalto l’aspetto desiderato.


      Per software non commerciale si intende shareware o open source.
  3



                                               9
CAPITOLO 2. BENCHMARKS


2.1.1     Il profiler HPROF
    HPROF genera le informazioni relative al profiling attraverso le chiamate a
JVM TI, le chiamate di ritorno dagli eventi della JVM TI e attraverso l’iniezione
di byte code nelle classi caricate dalla VM. Il metodo usato per il profiling dipende
dall’opzione con cui viene lanciato HPROF: l’opzione cpu=times inietta il byte
code all’ingresso e all’uscita di ogni metodo, l’opzione heap inietta il byte code nel
metodo <init> della classe java.lang.Object ed in ogni ‘newarray’ visto all’interno
di tutti i metodi, mentre l’opzione cpu=sample utilizza un thread che, svegliandosi
                                                                `
dopo un determinato intervallo di tempo, campiona lo stack. E possibile utilizzare
questo strumento attraverso il comando

java -agentlib:hprof[=opzioni] ClasseDaAnalizzare

     dove la ClasseDaAnalizzare ` la classe alice.tuprolog.Agent con, come primo
                                  e
parametro, la teoria di test. In particolare, per fare il profiling dei tempi di ese-
cuzione e dell’uso dell’heap dell’interprete tuProlog, vengono usati i comandi con
le seguenti opzioni: hprof=cpu=times e hprof=heap=sites. Il primo presenta i
dati riguardanti al tempo effettivo speso da un metodo in millisecondi, il numero
di volte che quel metodo ` stato chiamato da un altro metodo e il trace dello stack
                           e
che ha causato quella chiamata. Il secondo comando mostra gli oggetti che sono
stati creati durante l’esecuzione del programma. In particolare si possono trovare
informazioni riguardanti la memoria occupata e il numero di oggetti vivi in un
certo trace, nonch´ la memoria allocata e il numero di oggetti allocati durante l’e-
                   e
secuzione dell’intero programma nello stesso trace. Questo permette di analizzare
il comportamento del garbage collector durante l’esecuzione della teoria. Inoltre ad
ogni oggetto viene associato il trace dello stack che ha generato la sua allocazione
in memoria, permettendo di fatto di risalire a quale metodo lo ha istanziato. Uno
degli svantaggi di usufruire di un’analisi metodo a metodo, anche se compensato
dalla precisione delle misure, ` quello di non poter sfruttare questo procedimento
                               e
per teorie il cui calcolo computazionale richieda tempi lunghi, in quanto il pro-
filer allunga, anche notevolmente, i tempi di esecuzione. Di questo e dei motivi
che hanno portato alla scelta delle opzioni descritte in precedenza viene discusso
comunque pi` approfonditamente nei Capitoli 3 e 4.
              u

                                         10
2.2. TEORIE DI TEST


2.2        Teorie di test
     Le teorie di test sono una parte del benchmark importante quanto il profiler.
Esse infatti determinano il comportamento dell’interprete durante la risoluzione
delle clausole e perci` devono essere scelte con cura, in modo tale da permettere
                       o
un’analisi il pi` completa possibile. In questa dissertazione vengono presentati
                 u
i risultati dei test sul core tuProlog e sulla libreria BasicLibrary, senza testare
le librerie aggiuntive come IOLibrary, JavaLibrary o ISOLibrary, anche se queste
vengono caricate automaticamente durante l’inizializzazione del motore tuProlog.
L’attenzione ` anche rivolta alla scalabilit` del sistema e alcune delle teorie uti-
               e                            a
lizzate sono scritte in modo tale da permettere vari test sulla scalabilit` senza la
                                                                          a
necessit` di pesanti modifiche alla teoria stessa o l’introduzione di nuove teorie.
         a

    I risultati trovati in studi precedenti [6], con lo scopo di confrontare tuPro-
log con altri interpreti Prolog basati su Java, vennero trovati utilizzando teorie di
test note, utilizzate in benchmark atti a misurare la velocit` di risoluzione delle
                                                                a
teorie. Per mantenere una certa continuit` e per poter confrontare i risultati del
                                              a
lavoro svolto in passato si ` deciso di mantenere, per quanto possibile, alcune delle
                             e
teorie gi` utilizzate. Si noti comunque che i sistemi hardware e software su cui
          a
sono stati fatti i test passati e quelli qui descritti sono completamente differenti4 .
Questo rende il confronto fra i risultati ottenuti solo indicativo. Tuttavia, alcune
delle teorie utilizzate devono essere omesse completamente dall’analisi dei tempi
di esecuzione totale (non dall’analisi dei tempi di esecuzione dei vari metodi) per
i motivi illustrati nel capitolo 3.

    Le teorie utilizzate sono: Crypt, Poly, Qsort, Queens, Query, Tak, Einstein’s
riddle, Spanning tree e Switch square. Le prime sei fra queste sono teorie che
erano gi` state usate come benchmark, mentre le altre sono state introdotte so-
         a
lamente ora. Einstein’s riddle, Spanning tree e Switch square permettono inoltre
di ingrandire l’albero di risoluzione delle teorie modificando l’obiettivo. In questo

     Il sistema su cui sono stati ricavati i risultati antecedenti a quelli qui descritti era equipaggiato
   4

con un processore Pentium III 800 MHz, 256 MB di RAM su Windows 2000 e J2SE 1.5.0 09. Il
sistema attuale consiste in un processore Pentium IV 2.6 GHz, con 1 GB di RAM su Windows
XP Home Edition e J2SE 1.6.0 04.


                                                   11
CAPITOLO 2. BENCHMARKS


modo ` possibile incrementare o diminuire il lavoro svolto dal motore tuProlog
        e
senza modificare la teoria in s´, consentendo di analizzare la scalabilit` del siste-
                                e                                          a
ma. Esse svolgono il seguente lavoro: Crypt, data una formula matematica nota,
ne cerca la soluzione; Poly dato un polinomio nella forma 1 + x + y + z lo eleva
alla decima potenza attraverso la trasformazione simbolica della formula; Qsort
riordina una lista di numeri in modo crescente; Queens ` la versione estesa a nove
                                                           e
regine del pi` famoso problema delle 8 regine [1]; Query interroga un database
              u
contenente per ogni nazione la rispettiva dimensione e il numero di cittadini e
restituisce, conoscendo gi` il nome di una nazione, quella con la densit` pi` simile
                           a                                              au
ad essa; Einstein’s riddle tenta di risolvere un indovinello nel quale viene chiesto
chi ` il proprietario di un certo animale data una serie di indizi riguardo a cinque
    e
persone di diversa nazionalit`, residenti in case di colore diverso e con una distinta
                              a
preferenza in termini di animali domestici, marche di sigarette e bevande; Span-
ning tree data una lista di collegamenti fra nodi, ognuno con un certo peso, trova
appunto lo spanning tree [1] di quell’albero; Switch square data una matrice 3x3,
i cui valori possono essere vero o falso, tenta di negare i valori posizionati ad una
distanza di Manhattan uguale o inferiore ad 1 da una certa cella e, attraverso una
sequenza di commutazioni delle celle, cerca di rendere tutti i valori della matrice
veri.




                                         12
Capitolo 3

Analisi dei tempi di esecuzione

    In questo capitolo vengono presentati i risultati ottenuti dal profiling delle
teorie di test esposte precedentemente. In particolare vengono mostrati quali sono
i tempi di esecuzione totali delle teorie e i tempi di esecuzione dei vari metodi
utilizzati durante la loro risoluzione. I dati ottenuti vengono poi elaborati in modo
da mettere in evidenza quali sono i punti fondamentali su cui il motore deve essere
migliorato. Per fare ci` viene prima messa alla prova la scalabilit` del sistema,
                         o                                              a
facendo il profiling con teorie via via pi` complesse ed in secondo luogo vengono
                                           u
costruiti i grafi delle chiamate ai metodi, in modo da evidenziare quali metodi
effettuano le chiamate pi` costose da un punto di vista computazionale.
                           u



3.1     Metodo di profiling
    Come gi` detto, i dati risultanti dal profiling devono fornire il tempo di ese-
             a
cuzione totale della teoria, il tempo di esecuzione dei metodi e, indirettamente,
per ognuno di essi, i tempi di esecuzione dei metodi innestati. Ci` ` possibile in
                                                                    oe
quanto il profiler HPROF mette a disposizione il trace dello stack che ha generato
la chiamata ad un particolare metodo, oltre ovviamente al tempo di esecuzione del
metodo (mostrato come percentuale sul tempo di esecuzione totale) e al numero
di volte in cui ` stato chiamato. Il comando utilizzato per fare ci` ` il seguente
                e                                                  oe


java -agentlib:hprof=cpu=times alice.tuprolog.Agent teoria.pl

                                         13
CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE


    dove la classe Agent, contenuta nel package alice.tuprolog, ` uno strumento che
                                                                e
accetta come parametro una teoria Prolog scritta in un file di testo e, dopo aver
tentato di risolverla, stampa sullo standard output il risultato della valutazione.
tuProlog permette di valutare una teoria in altri tre modi: lanciando un’interfaccia
grafica ed inserendo la teoria in un’apposita TextBox, in un ambiente interattivo
attraverso la classe alice.tuprologx.ide.CUIConsole oppure istanziando un oggetto
Prolog in una classe Java. Il metodo utilizzato, a differenza degli altri, permette
per` di isolare il motore tuProlog, in modo da non dover estromettere dal profiling
    o
i dati non dovuti alla risoluzione, come ad esempio l’istanziazione della GUI.

    Per misurare il tempo di esecuzione in modo ottimale il file teoria.pl viene
costruito in modo da separare tre diversi processi che avvengono durante la riso-
luzione della teoria: l’inizializzazione del motore e il caricamento delle librerie1 ,
la lettura delle clausole di Horn e la risoluzione vera e propria. Vengono quin-
di dapprima misurati i tempi di esecuzione della lettura della teoria assieme alla
sua risoluzione risolvendo un certo obiettivo2 . Successivamente lo stesso obiet-
tivo viene risolto per undici volte e viene sottratto il tempo di esecuzione pre-
cedentemente trovato. Questo ` equivalente a misurare undici volte il tempo di
                                  e
esecuzione dell’obiettivo pi` una volta il tempo di lettura della teoria per poi sot-
                             u
        `
trarlo. E inoltre necessario evitare di misurare il tempo di creazione della JVM
e per fare ci` viene scritta un’ulteriore teoria in cui viene usato il metodo Ja-
             o
va java.lang.System.currentTimeMillis prima e dopo l’esecuzione dell’obiettivo. Il
codice Prolog della teoria indicata risulta il seguente:

time(T) :- class(’java.lang.System’) <- currentTimeMillis returns T.
go(File) :- time(A), consult(File), time(B), C is B-A, print(C).

   dove File rappresenta il nome completo del file di testo in cui ` contenuta la
                                                                     e
teoria da valutare. All’interno di questo file sono contenute le seguenti clausole, le
quali permettono di valutare il tempo di lettura ed esecuzione:
          I tempi in cui questi processi avvengono sono dovuti alla JVM e non al motore tuProlog in
      1

s´.
 e
     Per diminuire la dispersione delle misure ` stato misurato dodici volte il tempo di esecuzione
                                               e
      2

dell’obiettivo e sottratto il valore massimo e minimo trovato. Il tempo di esecuzione ` la media
                                                                                         e
dei valori rimanenti.


                                                   14
3.2. TEMPI DI ESECUZIONE DEI METODI


:- solve(goAndRepeat).
:- solve(go).
goAndRepeat :- goN(11).
go :- goal().
goN(0).
goN(Z) :- goal(), W is Z-1, goN(W).

   dove goAndRepeat risolve undici volte l’obiettivo goal().


3.2     Tempi di esecuzione dei metodi
    Nonostante il metodo java.lang.System.currentTimeInMillis restituisca un tem-
po in millisecondi, la granularit` del valore dipende dal sistema in cui ` ospitata
                                 a                                       e
la JVM e potrebbe essere maggiore di 1 ms. Nel sistema in cui sono avvenute le
misure non ` stato possibile misurare intervalli di tempo minori a 15 ms, il che
             e
fa pensare che lo stesso valore corrisponda alla granularit` del sistema. Questo
                                                             a
ha reso impossibile un’apprezzabile misurazione delle teorie Crypt, Poly, Qsort,
Queens e Query in quanto i tempi misurati contengono un errore sulla misura
troppo elevato.


        Teoria            Tempo di esecuzione (ms) Errore relativo %
        Crypt                                 1669            179,75
        Einstein’s riddle                   114598               2,62
        Poly                                    31           9677,42
        Qsort                                  671            447,09
        Queens                                2574            116,55
        Query                                  312            961,54
        Spanning tree                        18034              16,64
        Switch square                        93787               3,20
        Tak                                 105721               2,84

Tabella 3.1: Tempi di esecuzione per cento risoluzioni e errore relativo calcolato
per una singola esecuzione.

   Dalla Tabella 3.1 si evince chiaramente che la misurazione dei tempi di let-
tura della teoria e risoluzione dell’obiettivo non possono essere misurati con una

                                        15
CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE


buona precisione. Nella Tabella 3.2 vengono quindi illustrati i tempi delle teorie
Einstein’s riddle, Spanning tree, Switch square e Tak i quali hanno errori relativi
ragionevolmente contenuti. La distinzione fra le due modalit` di esecuzione ha
                                                               a
lo scopo di mettere in luce quali sono le parti del motore tuProlog che possono
causare una degradazione delle performance.


       Teoria            Lettura esec (ms) Esec (ms) Esec/Lettura esec %
       Einstein’s riddle             13807     13331                 96,6
       Spanning tree                  2216      1868                 84,3
       Switch square                 10110      9628                 95,2
       Tak                           11373     10797                 94,9

                      Tabella 3.2: Tempi di lettura ed esecuzione.

Si pu` quindi affermare che il tempo di lettura risulta essere all’incirca costante al
      o
variare della teoria3 . I metodi coinvolti nella risoluzione dell’obiettivo occuperan-
no la maggior parte del tempo di esecuzione totale e questo permette un profiling
senza distinguere fra lettura ed esecuzione, come ` stato fatto fin d’ora, dato che
                                                      e
non valutare i metodi coinvolti durante la prima fase non comporta una perdita
di informazione significativa.

     Di seguito, nella Tabella 3.3, vengono presentati i risultati del profiling, ese-
guiti nei modi descritti precedentemente. Per ogni teoria ci si limita a presentare
i risultati di quei metodi il cui tempo impiegato a terminare4 ` superiore o uguale
                                                                e
al 2% del tempo di esecuzione totale.




     Nel caso di Spanning tree, la teoria pi` lunga, il numero di righe che il motore deve leggere
                                            u
   3

` 186, mentre nel caso di Tak, quella pi` corta, il numero di righe ` 29.
e                                        u                           e
     Il tempo impiegato ad un metodo per terminare non comprende il tempo impiegato ai metodi
   4

innestati in esso ad essere eseguiti.


                                               16
3.2. TEMPI DI ESECUZIONE DEI METODI




Teoria        Nome metodo                              Tempo esec % N. chiamate
              java.lang.Object.wait                           41,65           2
Crypt
              java.lang.AbstractStringBuilder.append           2,27       60583
              alice.tuprolog.Var.occurCheck                   21,35    14909053
              alice.tuprolog.Struct.getTerm                   14,24    30803506
              alice.tuprolog.Var.free                          6,01     4676006
              java.util.AbstractList$Itr.next                  4,60     4251755
              alice.tuprolog.Struct.getArity                    3,9    14871224
E.’s riddle   java.util.ArrayList.get                          3,82     5599360
              alice.tuprolog.Var.unify                         3,59     2488524
              alice.tuprolog.Struct.unify                      3,54     2482605
              java.util.AbstractList$Itr.hasNext               3,49     4998320
              java.util.ArrayList.add                          3,27     5000191
              alice.tuprolog.Var.getTerm                       2,53     9374073
              java.lang.AbstractStringBuilder.append           5,01       34179
              java.io.StringReader.read                        3,59       24662
              alice.tuprolog.Tokenizer.readNextToken           3,12        8815
              java.lang.StringBuffer.append                     2,96       32544
Poly
              alice.tuprolog.Tokenizer.readToken               2,92       21835
              java.io.StreamTokenizer.nextToken                2,21       17063
              alice.tuprolog.Struct.toString                   2,21        1986
              java.io.StreamTokenizer.read                     2,12       24662
              alice.tuprolog.Var.occurCheck                    3,65       24612
              java.lang.AbstractStringBuilder.append           3,58       37404
Qsort         alice.tuprolog.Struct.getTerm                    3,28       65039
              java.lang.StringBuffer.append                     2,22       35912
              java.io.StringReader.read                        2,05       22652
Queens        java.lang.Object.wait                           36,27            2
              java.lang.AbstractStringBuilder.append            3,9       34855
              java.io.StringReader.read                        2,73       24285
Query         alice.tuprolog.Tokenizer.readNextToken           2,29        8534
              alice.tuprolog.Tokenizer.readToken               2,23       21002

                                        17
CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE


             java.lang.StringBuffer.append              2,13     30505
             java.lang.Object.wait                    28,19         6
             alice.tuprolog.Var.occurCheck             4,88    531993
             alice.tuprolog.Struct.getTerm             4,24   1453666
             alice.tuprolog.Var.unify                  3,82    546668
 S. tree     alice.tuprolog.Var.free                   2,80    451853
             java.util.ArrayList.<init>                2,57    732603
             alice.tuprolog.Struct.unify               2,48    295052
             alice.tuprolog.Var.getTerm                2,26   1506972
             alice.tuprolog.Term.match                 2,01    128442
             alice.tuprolog.Var.unify                  7,95   3632513
             alice.tuprolog.Struct.unify               7,92   2719626
             alice.tuprolog.Var.free                   4,70   2522186
             java.util.AbstractList$Itr.next           4,13   2415736
             java.util.ArrayList.get                   3,99   3694306
             alice.tuprolog.Int.unify                  3,42   1849876
             alice.tuprolog.Struct.copy                3,39   1492772
 S. square   alice.tuprolog.Var.getTerm                3,22   6554696
             java.lang.AbstractStringBuilder.append    3,14   1691076
             java.util.AbstractList$Itr.hasNext        3,02   2821175
             java.util.ArrayList.add                   2,83   2475406
             alice.tuprolog.Var.copy                   2,77   1118445
             java.util.IdentityHashMap.get             2,35   1118445
             alice.tuprolog.Var.rename                 2,18    561971
             java.lang.StringBuffer.append              2,00   1677681
             alice.tuprolog.Var.unify                  5,76   3065460
             alice.tuprolog.Var.free                   3,74   2081312
             java.util.ArrayList.<init>                3,25   3259113
             java.util.AbstractList$Itr.hasNext        3,17   3194571
             java.lang.AbstractStringBuilder.append    3,04   1947463
             java.util.AbstractList$Itr.next           2,78   1823163
 Tak         java.util.ArrayList.get                   2,65   2716581
             alice.tuprolog.Var.getTerm                2,60   6292230

                                      18
3.2. TEMPI DI ESECUZIONE DEI METODI


              alice.tuprolog.Var.copy                               2,47       1193928
              java.util.AbstractList$Itr.<init>                     2,35       3388196
              java.util.ArrayList.add                               2,23       2210364
              alice.tuprolog.Var.rename                             2,13        645368
              alice.tuprolog.Int.unify                              2,12       1355254
                           Tabella 3.3: Analisi dei metodi.




    Come si pu` notare, in tre delle nove teorie, il metodo che impiega pi` tempo a
                o                                                         u
terminare ` java.lang.Object.wait. Questo metodo viene lanciato dalla JVM (nel
            e
caso si tratti del client HotSpot della JVM e l’algoritmo usato sia seriale) e per-
mette al garbage collector di ripulire parte dell’heap quando non ` pi` possibile
                                                                      eu
promuovere oggetti dallo young generation all’old generation [4]. Una spiegazione
pi` approfondita a riguardo viene data nel capitolo seguente. Per tutti gli altri
  u
metodi risulta difficile fare una ragionevole analisi basata su di una singola teo-
ria e, come detto nei capitoli precedenti, si deve ricercare un approccio che possa
mettere in luce i miglioramenti in un ambito di utilizzo il pi` eterogeneo possibile.
                                                              u
Nella Tabella 3.4 vengono sommati i tempi di esecuzione relativi di tutti i metodi
(anche quelli non inclusi nella Tabella 3.3). Nell’aggregare i risultati delle varie
teorie ` stato scelto di sommare semplicemente i risultati parziali senza dare alcun
       e
peso ai tempi di esecuzione delle teorie. Infatti, come si pu` vedere nell’analisi
                                                                 o
della scalabilit`, modificando l’obiettivo di una teoria, in modo da allungare o ac-
                a
corciare l’albero di ricerca di una soluzione, il tempo per ottenere una risposta,
rispettivamente, cresce o diminuisce linearmente con il numero di foglie dell’albero
visitate dalla macchina a stati finiti. Tuttavia i tempi di esecuzione relativi dei
vari metodi rimangono costanti. Per questo motivo dare un peso a questi tem-
pi significherebbe sbilanciare l’analisi complessiva a favore di una teoria anzich´  e
un’altra. Per la stessa ragione nella Tabella 3.4 viene omesso il numero di chiamate
ai metodi.

   Sempre dalla Tabella 3.4 si evince che il metodo java.lang.Object.wait ` ancora
                                                                          e
quello che occupa la maggior parte del tempo di esecuzione del motore tuProlog.

                                         19
CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE


               Nome metodo                            Tempo esec %
               java.lang.Object.wait                         12,15
               alice.tuprolog.Var.occurCheck                   3,70
               alice.tuprolog.Struct.getTerm                   3,06
               alice.tuprolog.Var.unify                        3,05
               java.lang.AbstractStringBuilder.append          2,82
               alice.tuprolog.Var.free                         2,61
               alice.tuprolog.Struct.unify                     2,25
               java.util.AbstractList$Itr.next                 1,88
               java.util.AbstractList$Itr.hasNext              1,80
               alice.tuprolog.Var.getTerm                      1,72
               java.util.ArrayList.get                         1,72
               java.lang.StringBuffer.append                    1,67
               java.util.ArrayList.<init>                      1,49
               java.util.ArrayList.add                         1,37
               java.io.StringReader.read                       1,16
               java.util.AbstractList$Itr.<init>               1,08
               alice.tuprolog.Tokenizer.readNextToken          1,01
               alice.tuprolog.Var.copy                         1,01

                          Tabella 3.4: Analisi dei metodi totale.

Eliminando, o limitando, il numero di chiamate ad esso comporterebbe un miglio-
ramento del tempo di esecuzione di circa il 12% sul tempo totale5 . Purtroppo,
escludendo il metodo Java gi` citato, non esistono situazioni in cui l’utilizzo di
                              a
una funzione ` predominante rispetto alle altre, anche se i metodi nella Tabel-
               e
la 3.4 rappresentano circa la met` del tempo di esecuzione totale. Questo dato
                                  a
indirizza sicuramente ad una pi` attenta analisi di questi metodi.
                                u



3.3       Analisi della scalabilit`
                                  a
    In questa parte della dissertazione viene data una dimostrazione di come la
relazione fra numero di stati visitati nell’albero di ricerca e numero di chiamate ai
metodi utilizzati sia lineare. Per fare ci` ` opportuno prendere come teoria di rife-
                                          oe

     Questa ipotesi, se pur plausibile, non ` del tutto veritiera. A causa della lentezza del profiler
                                            e
   5

HPROF non ` stato infatti possibile analizzare teorie di una certa complessit` computazionale e
              e                                                                  a
il valore di miglioramento potrebbe essere sottostimato.


                                                 20
`
                                                        3.3. ANALISI DELLA SCALABILITA


rimento la teoria Switch square che permette di ingrandire o rimpicciolire l’albero
di ricerca solamente modificando l’obiettivo e calcolare anche il numero di stati in
cui si deve transitare per trovare una soluzione. La Tabella 3.5 mostra per ogni
obiettivo valutato il tempo di esecuzione della teoria6 e i cinque metodi con tempo
di esecuzione pi` elevato con il relativo numero di chiamate per quel metodo.
                u



 N. stati e Tempo esec (ms) Nome metodo                         N. chiamate
                            alice.tuprolog.Struct.unify             1947041
                            alice.tuprolog.Var.unify                2584249
 3 + 6! 247837              alice.tuprolog.Var.free                 1802505
                            java.util.ArrayList.get                 2639270
                            java.util.AbstractList$Itr.next         1725777
                            alice.tuprolog.Struct.unify             3876572
                            alice.tuprolog.Var.unify                5181011
 3 + 2 ∗ 6! 488623          alice.tuprolog.Var.free                 3601750
                            java.util.AbstractList$Itr.next         3449996
                            java.util.ArrayList.get                 5276156
                            java.lang.Object.wait                         2
                            java.lang.ref.ReferenceQueue.remove           4
                            alice.tuprolog.Struct.unify             5813154
 3 + 3 ∗ 6! 1898223         alice.tuprolog.Var.unify                7768221
                            alice.tuprolog.Var.free                 5398379
                            java.util.AbstractList$Itr.next         5173233
                            java.util.ArrayList.get                 7911406

              Tabella 3.5: Analisi della scalabilit` del motore tuProlog.
                                                   a


   La Tabella 3.5, oltre a mostrare la linearit` fra stati visitati e numero di chia-
                                                a
mate ad un metodo, mostra anche come il tempo di esecuzione risulti lineare in
rapporto all’aumentare dei nodi nell’albero di risoluzione. Questo dimostra una
buona scalabilit` del sistema fino alla risoluzione dell’obiettivo con 3 + 2 ∗ 6! stati,
                 a
mentre le prestazioni degradano nella risoluzione dell’obiettivo con 3 + 3 ∗ 6! stati
a causa dell’intervento del garbage collector.

     Si tenga in considerazione che il tempo di esecuzione ` pregiudicato dal profiler HPROF che
                                                            e
   6

rallenta l’esecuzione di tuProlog. Per questo motivo non deve essere confrontato con quello della
Tabella 3.3, ma solamente con quello degli altri obiettivi.


                                               21
CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE


3.4      Grafo delle chiamate
    Con lo scopo di analizzare pi` in dettaglio i singoli metodi con i tempi di esecu-
                                  u
zione pi` elevati (si veda la Tabella 3.4) vengono esaminate le chiamate ad ognuno
         u
dei metodi stessi. Dai risultati di questa analisi ` possibile comprendere se l’elevato
                                                   e
tempo di esecuzione di una funzione ` dovuto all’implementazione della funzione
                                        e
stessa oppure all’uso troppo intenso della funzione da parte di altri metodi. Di
conseguenza ` possibile orientare la riscrittura del codice in una delle due dire-
               e
zioni. Per lo stesso principio che ha portato all’aggregazione dei risultati parziali
delle varie teorie ed esposto durante la discussione sull’analisi della scalabilit`, lo
                                                                                   a
studio ` stato realizzato esaminando le chiamate complessivamente pi` utilizzate,
        e                                                                 u
senza dare peso ai tempi di esecuzione delle singole teorie. Per ogni singolo metodo
presente nella Tabella 3.4 ` stato esplorato lo stack allo scopo di trovare quale fu
                             e
la prima funzione del package alice a generarne l’esecuzione. Questo accorgimento
` dovuto al fatto che solamente il codice dei metodi del package alice pu` essere
e                                                                              o
riscritto, quindi le chiamate fra metodi java (senza tenere conto del fatto che sono
da considerarsi gi` ottimizzate) non aggiungono informazione all’analisi7 .
                    a

    Il risultato dello studio ` la Figura 3.1, la quale mostra per ogni metodo,
                              e
rappresentato come nodo nel grafo (si faccia riferimento alla Tabella 3.6 per cono-
scere a quale metodo corrisponde ogni nodo), quali sono i suoi chiamanti attraverso
una freccia entrante. Una freccia uscente ed entrante nello stesso nodo indica una
chiamata ricorsiva e per ognuna delle frecce viene indicata in quale percentuale
un determinato metodo viene eseguito per causa del chiamante sul totale delle
chiamate8 .




     L’unico metodo, inserito nella Figura 3.1, il cui chiamante fa parte del package java `
                                                                                           e
  7

java.lang.Object.wait.
     Vengono visualizzati i chiamanti con percentuali uguali o superiori al 5%.
   8



                                            22
3.4. GRAFO DELLE CHIAMATE




               N. nodo   Nome metodo
                     0   java.io.StringReader.read
                     1   alice.tuprolog.Var.unify
                     2   java.util.ArrayList.add
                     3   alice.tuprolog.Var.getTerm
                     4   alice.tuprolog.Struct.unify
                     5   alice.tuprolog.Var.occurCheck
                     6   alice.tuprolog.Var.copy
                     7   alice.tuprolog.Struct.getTerm
                     8   alice.tuprolog.Tokenizer.readNextToken
                     9   java.util.AbstractList$Itr.hasNext
                    10   alice.tuprolog.Var.free
                    11   java.lang.Object.wait
                    12   java.util.ArrayList.get
                    13   java.util.AbstractList$Itr.<init>
                    14   java.util.AbstractList$Itr.next
                    15   java.lang.StringBuffer.append
                    16   java.lang.AbstractStringBuilder.append
                    17   java.util.ArrayList.<init>

Tabella 3.6: Associazione fra il numero identificativo di un nodo nella Figura 3.1
e il metodo che esso rappresenta.




                                       23
CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE




                                                                                                                                                                                                            ClauseStore.deunify
                                                                                                                        Int.unify
                                                                                                                         36                                                                                   11
                                  100
                                                                                                                                                                                             60                                    9     SubGoalTree.addChild
                                            0                                                                      1                                                                                    2
                                                                                                            61                                                                                               18
                                                Int.unify




                                       13                                                                                                                                                          14
                                                                                                                           18
                                                       40
                                                                       StateRuleSelection.doJob                                      25
                                                                                                        7                                  Term.match
                                            3                                                                      4                                                                                    5
                                                             24
                                                                                                                                                                                                                                  85
                                                                                                                                    48
                                                 11




                                                                                                              10              68
                                                                                                                                                                                                                                  99      Tokenizer.readToken
                                99
           Struct.copy
                                            6                                                                      7                                                                                    8
                                                                                                                                    13
                                                                                                                       Term.match
                                             Struct.copy




                                                   9                                                                    75
                                                                                                         14                                                                                                                       100
                                                             71                                                                                                                                                                             java
                                 15                                                                                                         StateBacktrack.dojob
   ClauseStore.deunify                                                                                                               7
                                            9                                                                    10                                                                                     11
                Cl
                   au
                      se
                         St
                           or
                             e.r
                                eu
                                   n
                                 ify




                                        18                                                                               6
                                                       50                                                                                                                                          75
                                                                                                                                                                                                                                  12      ClauseStore.deunify
                                                                                                                                                 java
                                                                                                       15                            5
  SubGoalTree.getChild 13                                                    ClauseStore.deunify
                                        12                                                                       13                                                                                     14
                                                                  ClauseInfo.bodyCopy
                                                             6                                         12                                                                                     9
                                                                                                                                     7
                                   8
                                                                                                 ify




                                                                                                                                                                                       py
                                                                                                                                         Te
                           fy




                                                                                               un




                                                                                                                                            r




                                                                                                                                                                                    o
                         ni




                                                                                                                                           m




                                                                                                                                                                                  yC
                    eu




                                                                                               .re




                                                                                                                                            .m




                                                                                                                                                                                od
                                                Var.rename




                                                                                                                       Var.rename
                 e.d




                                                                                             re




                                                                                                                                                 at




                                                                                                                                                                                                            Term.unify
                                                                                                                                                                                 b
                                                                                          to




                                                                                                                                                   ch




                                                                                                                                                                              o.
               or




                                                                                        eS




                                                                                                                                                                            nf
             St




                                                                                     us




                                                                                                                                                                        eI
            se




                                                                                                                                                                       us
                                                                                      a
           au




                                                                                   Cl




                                                                                                                                                                        a
         Cl




                                                                                                                                                                     Cl




                                                                                                                         42                                                                                      6
                                                45
                                                             7                                                                      11
                                 27
       Struct.toString                                                                                                                     Struct.<init>                                                                                  ClauseStore.deunify
                                                                                                                                                                                                                                  17
                                                                  PrimitiveManager.identify
                                        15                                                                       16                                                                                     17
                                                                                                                                                             SubGoalTree.<init>              15
                                                                                  Struct.toString      28                            7                                                                                            6
                                                                                                                                                                                                    54
                                                  10                                                           5
                                                                                                                                                                                                                                       St
                                                                                                                                         Pr




                                                                                                                                                                                                                                          at
                                                                                                                                            im




                                                                                                                                                                                                                                            eR
                                                                                                                                                                                              ch
                                                                                                           at $




                                                                                                                                            iti
                                             Struct.<init>




                                                                                                         er er




                                                                                                                                                                                                                                              ul
                                                                                                                                                 ve




                                                                                                                                                                                            at
                                                                                                             or
                                                                                                       Op ag




                                                                                                                                                                                                                                             eS
                                                                                                                                                                                        .m
                                                                                                                                                    M
                                                                                                     et an




                                                                                                                                                                                                                                               el
                                                                                                                                                    an




                                                                                                                                                                                       m




                                                                                                                                                                                                                                                   ec
                                                                                                er rM




                                                                                                                                                                                        r
                                                                                                                                                        ag




                                                                                                                                                                                     Te




                                                                                                                                                                                                                                                   tio
                                                                                              st to




                                                                                                                                                         er




                                                                                                                                                                                                                                                        n.
                                                                                            gi era




                                                                                                                                                           .id
                                                                                                  .g




                                                                                                                                                                                                                                                        do
                                                                                                                                                             en
                                                                                          Re p




                                                                                                                                                                                                                                                           J
                                                                                        or O




                                                                                                                                                               tif




                                                                                                                                                                                                                                                             ob
                                                                                                                                                                 y
                                                                                      at
                                                                                    er
                                                                                  Op




Figura 3.1: Analisi delle chiamate ai metodi pi` utilizzati nell’esecuzione delle
                                               u
teorie.


                                                                                                                  24
Capitolo 4

Analisi dell’utilizzo della memoria

    Le stesse teorie presentate nel Capitolo 2 vengono ora utilizzate nel profiling
del motore con lo scopo di analizzare in quale modo tuProlog sfrutta la memoria
heap. Ad una prima discussione sulle modalit` di studio dell’interprete segue la
                                                  a
presentazione dei dati ottenuti, ricavati con il proposito di mettere in evidenza
quali sono gli oggetti la cui istanziazione alloca in modo pi` consistente questa
                                                                 u
risorsa. A questo fine viene valutata la memoria complessivamente allocata du-
rante la risoluzione di una teoria, senza considerare il fatto che il garbage collector
libera lo spazio occupato da quegli oggetti non referenziati in un certo momento
dell’esecuzione. Infine, come nel capitolo precedente, vengono analizzati quali so-
no i metodi che sfruttano maggiormente la memoria, con lo scopo di rendere la
riscrittura del codice del motore il pi` circoscritta e proficua possibile.
                                       u



4.1      Metodo di profiling
    Il profiling del motore tuProlog fornisce i dati riguardanti l’utilizzo della memo-
ria ed in particolare, per permettere il tipo di analisi introdotta precedentemente,
deve mettere a disposizione, per ogni oggetto, i dati relativi alla memoria com-
plessiva da esso allocata e il metodo che alloca quel oggetto. Il profiler HPROF
permette di ricavare queste informazioni attraverso il seguente comando:


java -agentlib:hprof=heap=sites,depth=16 alice.tuprolog.Agent tr.pl

                                          25
CAPITOLO 4. ANALISI DELL’UTILIZZO DELLA MEMORIA


     dove l’opzione hprof=heap=sites visualizza, per ogni metodo incluso in un
certo trace dello stack e per ogni oggetto da esso istanziato, i seguenti dati: il tra-
ce dello stack che ha generato la chiamata al metodo; la quantit` di memoria totale
                                                                  a
istanziata da quel determinato trace insieme al numero totale di istanze create del-
l’oggetto in questione. Si deve precisare che HPROF non fornisce la quantit` di    a
memoria totale occupata da un oggetto, ma bens` la quantit` di memoria occupata
                                                   ı          a
da esso escludendo lo spazio utilizzato dalle istanze di oggetti generati al suo in-
terno. In questo modo ` possibile affrontare un’analisi classe per classe, separando
                         e
ognuna di esse da parte del suo contenuto. Se si volesse studiare quanto una classe
sfrutta complessivamente la memoria sarebbe sempre possibile farlo analizzando lo
stack. L’opzione depth=16 serve invece ad aumentare la profondit` dello stack vi-
                                                                      a
sualizzato in output. Dato che si vogliono studiare quali sono i metodi del package
alice che causano l’istanziazione di un oggetto, anche indirettamente, ` ragione-
                                                                           e
vole impostare una profondit` del trace uguale a sedici per intercettare tutte le
                               a
chiamate, se pur a scapito di un profiling pi` lento. Come spiegato nell’analisi dei
                                              u
tempi di esecuzione la classe Agent accetta tr.pl come parametro (in questo caso
` il file di testo contente una delle nove teorie gi` presentate) e viene preferita alle
e                                                  a
altre modalit` di esecuzione di tuProlog in quanto permette di analizzare solo la
               a
parte del motore che ha il compito di risolvere la teoria.


4.2        Allocazione degli oggetti in memoria
    L’allocazione degli oggetti, oltre ad incrementare la quantit` di memoria di cui
                                                                 a
tuProlog deve disporre per risolvere una teoria, porta anche ad un aumento dei
tempi di esecuzione. Questo avviene sia a causa del tempo necessario alla JVM a
creare una nuova istanza di un oggetto in memoria, sia a causa del tempo neces-
sario al garbage collector per ripulire lo spazio non referenziato da alcun oggetto.
Inoltre l’uso improprio di questa risorsa pu` causare il lancio dell’errore OutOf-
                                               o
MemoryError1 , interrompendo la risoluzione della teoria.

       La Tabella 4.1 ` stata costruita sommando le quantit` di memoria istanzia-
                      e                                    a
   Questo errore viene lanciato da parte della virtual machine nel momento in cui, a causa della
   1

mancanza di spazio in memoria, non ` pi` possibile allocare un certo oggetto.
                                    eu

                                              26
4.2. ALLOCAZIONE DEGLI OGGETTI IN MEMORIA


te dai vari trace per lo stesso oggetto durante l’esecuzione di tuProlog. In questo
modo ` possibile valutare complessivamente quanto un determinato oggetto viene
       e
istanziato. Inoltre vengono omessi quegli oggetti che occupano uno spazio in me-
moria inferiore al 2% dello spazio totale allocato.



 Teoria        Nome oggetto                      M. allocata % M. allocata Byte
               java.lang.Object[]                         26,09           1631496
               char[]                                     15,44            965728
               java.util.ArrayList                         8,54            534280
               java.util.AbstractList$Itr                  7,68            480040
               alice.tuprolog.Struct                       5,80            362712
 Crypt
               java.lang.String                            4,83            302128
               alice.tuprolog.Term[]                       4,37            273128
               alice.tuprolog.Var                          3,85            240728
               byte[]                                      3,71            231960
               java.lang.StringBuffer                       2,32            145080
               java.lang.Object[]                         41,27          87078352
               char[]                                     10,15          21423200
               java.util.ArrayList                         9,92          20935528
               java.util.AbstractList$Itr                  8,49          17917864
               alice.tuprolog.Var                          3,88           8191384
 E.’s riddle
               alice.tuprolog.Struct                       3,26           6870200
               java.util.AbstractList$ListItr              3,22           6787896
               java.lang.String                            2,94           6207184
               java.util.LinkedList$Entry                  2,68           5652544
               alice.tuprolog.Term[]                       2,41           5087632
               char[]                                     33,16            798736
               java.util.LinkedList$Entry                 13,36            321784
               byte[]                                     12,04            290000
               java.lang.String                            6,47            155728
 Poly
               int[]                                       4,02             96728
               alice.tuprolog.Token                        3,17             76312

                                            27
CAPITOLO 4. ANALISI DELL’UTILIZZO DELLA MEMORIA


           java.util.regex.Matcher                 2,36    56824
           alice.tuprolog.Var                      2,24    54008
           java.lang.Object[]                     23,12   649056
           char[]                                 15,02   421856
           byte[]                                  8,63   242384
           java.util.ArrayList                     6,81   191344
           java.util.AbstractList$Itr              5,67   159112
Qsort
           java.lang.String                        5,02   141088
           alice.tuprolog.Struct                   4,69   131768
           alice.tuprolog.Var                      3,96   111224
           alice.tuprolog.Term[]                   3,49    98064
           java.util.LinkedList$Entry              2,08    58408
           java.lang.Object[]                     33,73   3742072
           char[]                                 10,43   1156760
           java.util.ArrayList                     9,96   1104856
           java.util.AbstractList$Itr              8,30    921016
           alice.tuprolog.Struct                   4,58    508408
           java.util.AbstractList$ListItr          3,50    388536
Queens
           java.lang.String                        3,02    335128
           alice.tuprolog.Term[]                   2,86    316936
           java.util.LinkedList$Entry              2,66    294712
           alice.tuprolog.Var                      2,47    273880
           alice.tuprolog.ExecutionContext         2,16    239552
           byte[]                                  2,09    231960
           java.lang.Object[]                     26,57   647232
           char[]                                 11,27   274544
           byte[]                                  9,52   231960
           java.util.ArrayList                     9,49   231088
Query      java.util.AbstractList$Itr              9,20   223984
           java.lang.String                        3,99    97192
           java.util.LinkedList$Entry              3,95    96160
           alice.tuprolog.Struct                   2,87    70008



                                     28
4.2. ALLOCAZIONE DEGLI OGGETTI IN MEMORIA


            alice.util.OneWayList                  2,39           58264
            java.lang.Object[]                    38,19        26544168
            java.util.ArrayList                   12,70         8831704
            java.util.AbstractList$Itr            11,46         7964704
            char[]                                 7,57         5262592
            java.util.LinkedList$Entry             4,90         3404920
S. tree     alice.tuprolog.Struct                  3,05         2122008
            alice.tuprolog.Var                     2,82         1957752
            alice.util.OneWayList                  2,67         1856008
            java.util.AbstractList$ListItr         2,43         1686392
            java.lang.String                       2,30         1595608
            alice.tuprolog.Term[]                  2,25         1563112
            java.lang.Object[]                    24,74        66566376
            alice.tuprolog.Struct                 17,78        47833088
            char[]                                16,87        45410744
            alice.tuprolog.Term[]                 12,56        33810088
S. square   alice.tuprolog.Var                     6,66        17926784
            java.lang.String                       5,05        13602072
            java.util.ArrayList                    3,78        10162824
            java.util.AbstractList$Itr             3,54         9532368
            java.lang.StringBuffer                  3,32         8947632
            java.lang.Object[]                    32,60       130756896
            char[]                                12,92        51823792
            java.util.ArrayList                    9,75        39111280
            java.util.AbstractList$Itr             8,21        32912632
            alice.tuprolog.Struct                  4,51        18097912
            alice.tuprolog.Var                     4,38        17576824
Tak
            java.lang.String                       3,88        15560176
            alice.tuprolog.Term[]                  3,54        14217224
            java.util.AbstractList$ListItr         2,57        10326264
            java.lang.StringBuffer                  2,57        10325736
            java.util.LinkedList$Entry             2,32         9301336



                                         29
CAPITOLO 4. ANALISI DELL’UTILIZZO DELLA MEMORIA


              alice.tuprolog.ExecutionContext                 2,03             8132024
                    Tabella 4.1: Analisi degli oggetti utilizzati.




    Come si pu` osservare, in otto delle nove teorie, l’oggetto pi` utilizzato ` un
                o                                                  u             e
array di Object. Esso viene utilizzato principalmente nella classe ArrayList per
mantenere un buffer nel quale viene memorizzata la lista in questione. Un altro
oggetto che compare vistosamente nella tabella ` l’array char[], che viene utilizzato
                                               e
prevalentemente per memorizzare delle stringhe nelle classi String e StringBuilder
(o nella sua versione synchronized StringBuffer). Nel grafo delle allocazioni si pu` o
vedere in modo pi` specifico quali sono i metodi che istanziano questi oggetti.
                   u

     Nella Tabella 4.3 vengono mostrati quali sono gli oggetti complessivamente
pi` utilizzati durante la risoluzione delle teorie. Per le stesse ragioni esposte nel-
   u
l’analisi della scalabilit` le varie percentuali di utilizzo della memoria degli oggetti
                          a
vengono sommate dando lo stesso peso alle varie teorie, sebbene la quantit` di     a
memoria totale istanziata da una di esse possa essere diversa da quella istanziata
dalle altre. A sostegno di questa tesi, nella Tabella 4.2, vengono elencati i sei og-
getti che hanno fatto misurare le percentuali di utilizzo della memoria pi` elevate
                                                                              u
durante la risoluzione della teoria Switch square. Le misurazioni sono state fatte
per ognuno dei tre obiettivi utilizzati nell’analisi dei metodi, i quali permettono
di cercare in 3 + 6!, in 3 + 2 ∗ 6! oppure in 3 + 3 ∗ 6! diversi stati prima di tro-
vare la soluzione della teoria. Anche se la precisione dei risultati non rispecchia
quella avuta nell’analisi dei tempi di esecuzione, si pu` comunque assumere, con
                                                             o
buona approssimazione, che al variare dell’obiettivo e del numero di stati visitati
nell’albero di ricerca la percentuale di spazio allocato in memoria da ogni oggetto,
rispetto allo spazio totale allocato, rimane costante. Come detto precedentemente,
questo permette di analizzare l’utilizzo della memoria semplicemente sommando i
dati contenuti nella Tabella 4.1.




                                          30
4.2. ALLOCAZIONE DEGLI OGGETTI IN MEMORIA


                 N. stati   Nome oggetto          M. allocata %
                            java.lang.Object[]             24,74
                            alice.tuprolog.Struct          17,78
                            char[]                         16,87
                 3 + 6!
                            alice.tuprolog.Term[]          12,56
                            alice.tuprolog.Var              6,66
                            java.lang.String                5,05
                            alice.tuprolog.Struct          23,23
                            char[]                         17,80
                            alice.tuprolog.Term[]          17,31
                 3 + 2 ∗ 6!
                            alice.tuprolog.Var             12,60
                            java.lang.String               10,97
                            java.lang.Object[]              8,87
                            alice.tuprolog.Struct          19,12
                            char[]                         18,37
                            alice.tuprolog.Term[]          13,94
                 3 + 3 ∗ 6!
                            java.lang.Object[]              9,97
                            java.lang.String                9,78
                            alice.tuprolog.Var              9,37

Tabella 4.2: Analisi dell’utilizzo della memoria da parte degli oggetti rispetto
all’obiettivo della teoria.




    Infine, nella Tabella 4.3, vengono esposti i risultati di questa operazione omet-
tendo gli oggetti che allocano meno dell’1% della memoria totale istanziata. L’a-
nalisi conferma quanto detto precedentemente. Gli oggetti Object[] e char[] sono
ancora i pi` utilizzati da parte di tuProlog occupando il 42,11% della memoria
            u
totale impiegata. Inoltre, ricordando che il profiler HPROF non ingloba nella mi-
sura della memoria allocata da un oggetto lo spazio occupato da oggetti innestati,
` possibile considerare questi due oggetti istanziati solamente dalle classi Array-
e
List, String e StringBuffer. Seguendo questa ipotesi le classi String e StringBuffer
allocano complessivamente il 20,68% della memoria, mentre la classe ArrayList ne
alloca il 35,30%. Sar` quindi importante, al momento di una futura implemen-
                      a
tezione del codice, considerare queste tre classi, le quali occupano nell’insieme il
55,98% della memoria totale.


                                        31
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi

Weitere ähnliche Inhalte

Was ist angesagt?

Tecniche di Test-driven development in ambito sicurezza informatica e rilevaz...
Tecniche di Test-driven development in ambito sicurezza informatica e rilevaz...Tecniche di Test-driven development in ambito sicurezza informatica e rilevaz...
Tecniche di Test-driven development in ambito sicurezza informatica e rilevaz...fcecutti
 
Progettazione di universal active filters e realizzazione di un software per ...
Progettazione di universal active filters e realizzazione di un software per ...Progettazione di universal active filters e realizzazione di un software per ...
Progettazione di universal active filters e realizzazione di un software per ...SamanthaGaio
 
Tesi Specialistica - Weka SMP
Tesi Specialistica - Weka SMPTesi Specialistica - Weka SMP
Tesi Specialistica - Weka SMPFabio Pustetto
 
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Davide Bravin
 
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleInterfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleLuigi De Russis
 

Was ist angesagt? (8)

Tecniche di Test-driven development in ambito sicurezza informatica e rilevaz...
Tecniche di Test-driven development in ambito sicurezza informatica e rilevaz...Tecniche di Test-driven development in ambito sicurezza informatica e rilevaz...
Tecniche di Test-driven development in ambito sicurezza informatica e rilevaz...
 
Progettazione di universal active filters e realizzazione di un software per ...
Progettazione di universal active filters e realizzazione di un software per ...Progettazione di universal active filters e realizzazione di un software per ...
Progettazione di universal active filters e realizzazione di un software per ...
 
Thesis marco de_marco
Thesis marco de_marcoThesis marco de_marco
Thesis marco de_marco
 
Tesi Specialistica - Weka SMP
Tesi Specialistica - Weka SMPTesi Specialistica - Weka SMP
Tesi Specialistica - Weka SMP
 
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
 
Tesi Tamiazzo09
Tesi Tamiazzo09Tesi Tamiazzo09
Tesi Tamiazzo09
 
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleInterfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
 
Algoritmo di Dijkstra
Algoritmo di DijkstraAlgoritmo di Dijkstra
Algoritmo di Dijkstra
 

Andere mochten auch

Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...MicheleDamian
 
Why should we take a political stand
Why should we take a political standWhy should we take a political stand
Why should we take a political standArun Nalamara
 
10 Reasons
10 Reasons10 Reasons
10 ReasonsM_Butler
 
Delingskulturen og offentlig virksomhet - Petter Bae Brandtzæg
Delingskulturen og offentlig virksomhet - Petter Bae BrandtzægDelingskulturen og offentlig virksomhet - Petter Bae Brandtzæg
Delingskulturen og offentlig virksomhet - Petter Bae BrandtzægBetaTrondheim
 
Mistakes You Are About To Make
Mistakes You Are About To MakeMistakes You Are About To Make
Mistakes You Are About To MakeBill Hunt
 

Andere mochten auch (6)

Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
 
Hindu dharma
Hindu dharmaHindu dharma
Hindu dharma
 
Why should we take a political stand
Why should we take a political standWhy should we take a political stand
Why should we take a political stand
 
10 Reasons
10 Reasons10 Reasons
10 Reasons
 
Delingskulturen og offentlig virksomhet - Petter Bae Brandtzæg
Delingskulturen og offentlig virksomhet - Petter Bae BrandtzægDelingskulturen og offentlig virksomhet - Petter Bae Brandtzæg
Delingskulturen og offentlig virksomhet - Petter Bae Brandtzæg
 
Mistakes You Are About To Make
Mistakes You Are About To MakeMistakes You Are About To Make
Mistakes You Are About To Make
 

Ähnlich wie Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi

Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...Paolo Morandini
 
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...maaske
 
Valutazione sperimentale di tecnologie per la gestione dei dati per workflow ...
Valutazione sperimentale di tecnologie per la gestione dei dati per workflow ...Valutazione sperimentale di tecnologie per la gestione dei dati per workflow ...
Valutazione sperimentale di tecnologie per la gestione dei dati per workflow ...Francesco De Giorgi
 
CaputiDomenicoMagistrale
CaputiDomenicoMagistraleCaputiDomenicoMagistrale
CaputiDomenicoMagistraleDomenico Caputi
 
Utilizzo dei processi aziendali per la co simulazione di modelli dinamici
Utilizzo dei processi aziendali per la co simulazione di modelli dinamiciUtilizzo dei processi aziendali per la co simulazione di modelli dinamici
Utilizzo dei processi aziendali per la co simulazione di modelli dinamiciBesian Pogace
 
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...Idriss Riouak
 
Anomaly detection in network traffic flows with big data analysis techniques
Anomaly detection in network traffic flows with big data analysis techniques Anomaly detection in network traffic flows with big data analysis techniques
Anomaly detection in network traffic flows with big data analysis techniques Maurizio Cacace
 
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...Filippo Muscolino
 
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...DamianoRavalico
 
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...Francesco Komauli
 
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...maik_o
 
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Raffaele Bernardi
 
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...daniel_zotti
 
Publish/Subscribe EDI with Content-Based Routing
Publish/Subscribe EDI with Content-Based RoutingPublish/Subscribe EDI with Content-Based Routing
Publish/Subscribe EDI with Content-Based RoutingNicola Mezzetti
 
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...Public Light Manager - Una GUI per la gestione remota di un impianto di illum...
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...Gianluca Ritrovati
 
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...Francesco Cucari
 
Il tutorial di Python
Il tutorial di PythonIl tutorial di Python
Il tutorial di PythonAmmLibera AL
 
Monitoraggio di applicazioni software mediante modelli di Markov
Monitoraggio di applicazioni software mediante modelli di MarkovMonitoraggio di applicazioni software mediante modelli di Markov
Monitoraggio di applicazioni software mediante modelli di Markovrkjp
 

Ähnlich wie Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi (20)

Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
 
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
 
Valutazione sperimentale di tecnologie per la gestione dei dati per workflow ...
Valutazione sperimentale di tecnologie per la gestione dei dati per workflow ...Valutazione sperimentale di tecnologie per la gestione dei dati per workflow ...
Valutazione sperimentale di tecnologie per la gestione dei dati per workflow ...
 
CaputiDomenicoMagistrale
CaputiDomenicoMagistraleCaputiDomenicoMagistrale
CaputiDomenicoMagistrale
 
Utilizzo dei processi aziendali per la co simulazione di modelli dinamici
Utilizzo dei processi aziendali per la co simulazione di modelli dinamiciUtilizzo dei processi aziendali per la co simulazione di modelli dinamici
Utilizzo dei processi aziendali per la co simulazione di modelli dinamici
 
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
 
Anomaly detection in network traffic flows with big data analysis techniques
Anomaly detection in network traffic flows with big data analysis techniques Anomaly detection in network traffic flows with big data analysis techniques
Anomaly detection in network traffic flows with big data analysis techniques
 
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
 
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...
 
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
 
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
 
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
 
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
 
Publish/Subscribe EDI with Content-Based Routing
Publish/Subscribe EDI with Content-Based RoutingPublish/Subscribe EDI with Content-Based Routing
Publish/Subscribe EDI with Content-Based Routing
 
LEARNING OBJECT MODELLO DI RIFERIMENTO SCORM E AUTHORING APPLICATIONS
LEARNING OBJECT MODELLO DI RIFERIMENTO SCORM E AUTHORING APPLICATIONSLEARNING OBJECT MODELLO DI RIFERIMENTO SCORM E AUTHORING APPLICATIONS
LEARNING OBJECT MODELLO DI RIFERIMENTO SCORM E AUTHORING APPLICATIONS
 
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...Public Light Manager - Una GUI per la gestione remota di un impianto di illum...
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...
 
TesiEtta
TesiEttaTesiEtta
TesiEtta
 
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
 
Il tutorial di Python
Il tutorial di PythonIl tutorial di Python
Il tutorial di Python
 
Monitoraggio di applicazioni software mediante modelli di Markov
Monitoraggio di applicazioni software mediante modelli di MarkovMonitoraggio di applicazioni software mediante modelli di Markov
Monitoraggio di applicazioni software mediante modelli di Markov
 

Kürzlich hochgeladen

Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Associazione Digital Days
 
Programma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoProgramma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoQuotidiano Piemontese
 
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Associazione Digital Days
 
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Associazione Digital Days
 
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Associazione Digital Days
 
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Associazione Digital Days
 
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Associazione Digital Days
 
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Associazione Digital Days
 
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Associazione Digital Days
 

Kürzlich hochgeladen (9)

Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
 
Programma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoProgramma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 Torino
 
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
 
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
 
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
 
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
 
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
 
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
 
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
 

Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi

  • 1. ` ALMA MATER STUDIORUM - UNIVERSITA DI BOLOGNA ` FACOLTA DI INGEGNERIA Corso di Laurea Triennale in Ingegneria Informatica Tesi di Laurea in Fondamenti di Informatica L-B Analisi di prestazione dell’interprete tuProlog su piattaforma Java Candidato Relatore Michele Damian Chiar.mo Prof. Enrico Denti Anno Accademico 2007/08
  • 2.
  • 3. Indice Introduzione vii 1 Il motore tuProlog 1 2 Benchmarks 7 2.1 Profilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.1.1 Il profiler HPROF . . . . . . . . . . . . . . . . . . . . . . . 10 2.2 Teorie di test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3 Analisi dei tempi di esecuzione 13 3.1 Metodo di profiling . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.2 Tempi di esecuzione dei metodi . . . . . . . . . . . . . . . . . . . . 15 3.3 Analisi della scalabilit` . . . . . a . . . . . . . . . . . . . . . . . . . . 20 3.4 Grafo delle chiamate . . . . . . . . . . . . . . . . . . . . . . . . . . 22 4 Analisi dell’utilizzo della memoria 25 4.1 Metodo di profiling . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 4.2 Allocazione degli oggetti in memoria . . . . . . . . . . . . . . . . . 26 4.3 Analisi del garbage collector . . . . . . . . . . . . . . . . . . . . . . 32 4.4 Grafo delle allocazioni . . . . . . . . . . . . . . . . . . . . . . . . . 35 5 Confronto con la versione tuProlog 1.3 39 6 Conclusioni 41 i
  • 4.
  • 5. Elenco delle figure 1.1 Il pattern state che realizza la macchina a stati finiti . . . . . . . . 3 1.2 La macchina a stati finiti del motore tuProlog . . . . . . . . . . . . 4 3.1 Analisi delle chiamate ai metodi pi` utilizzati nell’esecuzione delle u teorie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 4.1 Analisi delle istanziazioni degli oggetti pi` allocati nell’esecuzione u delle teorie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 iii
  • 6.
  • 7. Elenco delle tabelle 3.1 Tempi di esecuzione per cento risoluzioni e errore relativo calcolato per una singola esecuzione. . . . . . . . . . . . . . . . . . . . . . . . 15 3.2 Tempi di lettura ed esecuzione. . . . . . . . . . . . . . . . . . . . . 16 3.3 Analisi dei metodi. . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.4 Analisi dei metodi totale. . . . . . . . . . . . . . . . . . . . . . . . . 20 3.5 Analisi della scalabilit` del motore tuProlog. . . . . . . . . . . . . a . 21 3.6 Associazione fra il numero identificativo di un nodo nella Figura 3.1 e il metodo che esso rappresenta. . . . . . . . . . . . . . . . . . . . 23 4.1 Analisi degli oggetti utilizzati. . . . . . . . . . . . . . . . . . . . . . 30 4.2 Analisi dell’utilizzo della memoria da parte degli oggetti rispetto all’obiettivo della teoria. . . . . . . . . . . . . . . . . . . . . . . . . 31 4.3 Analisi complessiva degli oggetti utilizzati. . . . . . . . . . . . . . . 32 4.4 Analisi del garbage collector. . . . . . . . . . . . . . . . . . . . . . . 35 4.5 Associazione fra il numero identificativo di un nodo nella Figura 4.1 e l’oggetto che esso rappresenta. . . . . . . . . . . . . . . . . . . . . 36 5.1 Comparazione dei tempi di esecuzione nelle singole teorie. . . . . . . 40 5.2 Comparazione dell’allocazione della memoria nelle singole teorie. . . 40 v
  • 8.
  • 9. Introduzione Il motore tuProlog ` un interprete per il linguaggio Prolog, scritto interamente e in Java e interoperabile con le librerie fornite dalla piattaforma di sviluppo JDK. Giunto recentemente alla versione 2.1, ha portato con s´ diversi cambiamenti dal e punto di vista strutturale. L’obiettivo del lavoro ` quello di analizzare le pre- e stazioni dell’interprete in modo tale da porre delle basi utili per un suo ulteriore miglioramento in versioni successive. Alla conclusione, all’eventuale revisore del- l’interprete, sar` chiaro su quali parti del codice dovr` orientare la sua attenzione a a per apportare dei miglioramenti. A questo proposito l’analisi viene scomposta in due sezioni, con lo scopo di mettere in luce l’utilizzo della cpu e l’allocazione della memoria heap da parte dei metodi e delle classi implementate dal motore. Per quanto riguarda le prestazioni in termini di velocit`, allo stato attuale, i dati a di- a sposizione si basano unicamente sui tempi di esecuzione di alcune teorie utilizzate come benchmark per interpreti Prolog e considerate standard per test prestazionali di questo tipo di motore. A causa della variazione del sistema hardware sul quale vengono eseguiti i test, queste teorie per` non garantiscono tempi di esecuzione ab- o bastanza elevati da poter essere misurati con un apprezzabile errore sulla misura. Per questo motivo ad esse devono essere aggiunte delle nuove teorie per ottimizzare il benchmark. Un altro obiettivo che il lavoro si pone ` quello di analizzare come e sono cambiate le prestazioni dell’interprete in seguito al passaggio dalla versione 1 alla versione 2, la quale ha introdotto alcune modifiche a livello architetturale. In particolare viene presa come riferimento l’ultima release di ognuna delle due versioni, le quali sono rispettivamente la release 1.3 e 2.1. La dissertazione ` strutturata in modo da rendere pi` comprensibile possi- e u bile il motivo delle scelte fatte durante il progetto. Il Capitolo 1 presenta il motore vii
  • 10. tuProlog, spiegando quali sono le caratteristiche principali dell’interprete e facendo un’analisi di alto livello del suo funzionamento. Nel Capitolo 2 vengono discussi i motivi che hanno portato alla scelta di HPROF come strumento di profiling, nonch´ le sue funzionalit` principali. Inoltre vengono presentate le teorie di test e a che hanno permesso di ricavare le informazioni utilizzate nell’analisi di tuProlog. Nei capitoli successivi si entra nella parte centrale del lavoro, esponendo queste informazioni e analizzando qual ` il loro significato. In particolare, nel Capitolo 3 e vengono analizzati i tempi di esecuzione, mentre nel Capitolo 4 viene analizzato l’utilizzo della memoria heap da parte di tuProlog. Nel Capitolo 5 si trova un confronto fra la pi` recente versione di tuProlog (2.1) e la versione 1.3. Questo u confronto viene fatto riferendosi ai tempi di esecuzione ed ai dati relativi all’uso della memoria. Infine, nel Capitolo 6, vengono tratte le conclusioni, esponendo quali sono le parti del motore che possono essere migliorate. viii
  • 11. Capitolo 1 Il motore tuProlog L’obiettivo per cui l’interprete tuProlog venne ideato fu quello di poter disporre di uno strumento in grado di realizzare dei componenti intelligenti da poter utiliz- zare in un’infrastruttura internet dinamica. La base sulla quale viene costruito ` il e linguaggio di programmazione logica dichiarativo Prolog. Sin dal primo interprete, scritto nel 1972, le implementazioni dei sistemi Prolog si pongono come obiettivo quello di ottimizzare fattori quali il tempo di esecuzione e l’utilizzo della memoria. tuProlog, scritto interamente in Java, si discosta da questa tendenza, introducendo nell’architettura dell’interprete i concetti legati alla programmazione orientata agli oggetti, con lo scopo di poterne sfruttare i vantaggi. Tra questi pregi, apprezzati quando si deve scrivere codice utilizzabile in infrastrutture intelligenti e sistemi dinamici, vi sono: la portabilit`, ovvero la facilit` con cui ` possibile distribuire a a e l’applicazione, legata solamente alla presenza della piattaforma Java; la riusabi- lit`, che permette il riutilizzo di componenti in diversi sistemi; la modularit`, che a a determina anche la leggerezza del core. Queste nozioni, ben note nell’ingegneria del software, vengono realizzate implementando i pattern descritti in seguito. In primo luogo viene considerata la riusabilit` e la modularit` dell’architet- a a tura del motore tuProlog. Esse vengono rese possibili grazie alla separazione delle responsabilit` del sistema. Ogni responsabilit` viene associata ad un singolo ma- a a nager il quale controlla parte del motore tuProlog, in modo tale che le librerie e i predicati primitivi siano indipendenti dal motore e possano essere sostituite o 1
  • 12. CAPITOLO 1. IL MOTORE TUPROLOG modificate preservando il funzionamento del sistema. Queste caratteristiche sono rese possibili grazie al pattern Fa¸ade [2], che riduce anche il numero di oggetti c che il cliente deve utilizzare, rendendo il sistema pi` semplice da gestire. Sono u presenti quattro tipi di manager per gestire diversi oggetti: il manager delle li- brerie, il manager delle primitive, il manager delle teorie e il manager degli stati della macchina a stati finiti. Il manager delle librerie rende possibile il caricamento delle librerie di predicati al bisogno, anche a runtime. Questa peculiarit`, oltre a a rendere estremamente configurabile tuProlog, fa si che il core metta a disposi- zione funzionalit` essenziali e quindi dia migliori prestazioni in termini di tempi a di esecuzione e utilizzo della memoria. Tuttavia esistono alcuni predicati che non sono stati inseriti nelle librerie, ma sono stati definiti nel motore. Essi sono quei predicati che influenzano il processo di risoluzione, come cut/0, quelli che sono troppo basilari per essere definiti altrove, come fail/0 e quelli che per ragioni di efficienza devono essere definiti vicino al core, come ’,’/2. A parte queste eccezioni tutti gli altri predicati sono contenuti all’interno di librerie, le cui seguenti sono caricate durante la fase di creazione del motore: la libreria BasicLibrary, la quale contiene i predicati pi` importanti, escludendo i predicati di I/O; la libreria IO- u Library che mette a disposizione alcuni dei predicati di input/output standard di Prolog, come write/1, read/1 e nl/0; la libreria ISOLibrary che definisce predicati standard ISO non definiti nelle due librerie precedenti; e JavaLibrary che definisce tutti quei predicati idonei a permettere l’interazione fra Prolog e Java. Tutte le altre librerie, come quelle definite dall’utente, possono essere caricate runtime. Il manager delle primitive ha il compito di riconoscere i predicati presenti all’interno delle teorie da quelli definiti nelle librerie o dall’utente. Questa operazione ` neces- e saria in quanto i due gruppi di predicati dovranno essere trattati differentemente durante il processo di risoluzione: i primi dovranno essere eseguiti come metodi Java ogni qualvolta la risoluzione di una teoria preveda prima la loro risoluzione, mentre gli altri saranno gestiti dalla macchina a stati finiti del motore tuProlog. Il parser del motore tuProlog legge la teoria Prolog riconoscendo la corretta sin- tassi e creando gli oggetti corrispondenti ai termini identificati. A supporto del parser il manager delle teorie crea il database delle clausole, a cui il motore far` a riferimento durante il processo di risoluzione e riconosce le direttive che devono essere eseguite immediatamente. Per questioni di ottimizzazione il corpo di una 2
  • 13. Figura 1.1: Il pattern state che realizza la macchina a stati finiti proposizione viene decomposto in sotto obiettivi non appena essa stessa viene rico- nosciuta e non durante la fase di risoluzione. La proposizione viene rappresentata in memoria tramite una struttura dati ad albero in cui ogni foglia rappresenta un sotto obiettivo. Infine il manager del motore si occupa di gestire i motori di risoluzione crean- do un’istanza della macchina a stati finiti per ogni teoria che debba essere risolta (situazione che potrebbe presentarsi nel caso le teorie siano innestate l’una nell’al- tra). Questa macchina, nel quale ogni stato rappresenta un passo nella risoluzione della teoria, ` di fondamentale importanza in quanto realizza il motore di riso- e luzione delle teorie. Inoltre, il manager del motore permette di disaccoppiare il motore di risoluzione tuProlog dal resto dell’architettura favorendo l’estensibilit`a della macchina a stati finiti, a cui diventa possibile aggiungere nuovi stati. Per realizzare tutto ci` viene usato il pattern State [2] che permette di istanziare og- o getti il cui comportamento dipende dallo stato interno. La classe Engine mantiene al suo interno sia lo stato attuale della macchina a stati finiti sia lo stato suc- cessivo al quale deve transitare, mentre gli stati vengono realizzati derivando la classe astratta State. Pi` dettagliatamente il motore comprende uno stato iniziale u (Init), quattro stati rappresentanti le attivit` svolte durante il processo di riso- a luzione (Goal Selection, Goal Evaluation, Rule Selection e Backtrack) e quattro stati finali rappresentanti i modi in cui la risoluzione potrebbe terminare (HALT, TRUE, TRUE CP e FALSE). 3
  • 14. CAPITOLO 1. IL MOTORE TUPROLOG Figura 1.2: La macchina a stati finiti del motore tuProlog Lo stato Init ` il punto di partenza e ha il compito di inizializzare il motore e di risoluzione estraendo gli obiettivi da valutare dalla teoria e creando un ogget- to che rappresenta il contesto nella quale l’obiettivo verr` valutato. Dopodich´ a e il controllo verr` passato allo stato Goal Selection il quale seleziona l’obiettivo a da valutare da una lista di obiettivi. Se questo obiettivo non viene trovato e il processo di esecuzione ` terminato si possono presentare due casi: se esiste un e punto di scelta e quindi la teoria pu` avere un’altra soluzione, lo stato finale sar` o a TRUE CP, altrimenti lo stato finale sar` TRUE. Se invece esiste un altro obiettivo a che pu` essere estratto deve essere valutato nello stato Goal Evaluation, a meno o che esso non rappresenti un numero, in qual caso la risoluzione termina nello stato FALSE. Se l’obbiettivo valutato nello stato Goal Evaluation rappresenta un pre- dicato primitivo allora la macchina a stati finiti transita nello stato Goal Selection o Backtrack, a seconda se la valutazione del predicato abbia avuto esito positivo o negativo, altrimenti transita nello stato Rule Selection e viene scelta una clausola compatibile per la risoluzione della teoria. In qualsiasi momento venga raggiunta una condizione di errore nello stato Goal Evaluation la macchina transita nello stato HALT e termina l’esecuzione. Nel caso non venga trovata nessuna clausola dal set di regole compatibili con l’attuale obiettivo allora lo stato successivo sar` a quello di Backtrack. Nello stato di Rule Selection viene preparato un nuovo con- testo di esecuzione, l’obiettivo viene unificato con la testa della clausola, il corpo della clausola viene aggiunto al risolvente, viene creato un nuovo punto di scelta ed il sistema transita nello stato di Goal Selection. Infine lo stato di Backtrack ha il 4
  • 15. compito di trovare una clausola compatibile dal contesto creato nell’ultimo punto di scelta aperto, se questa non viene trovata il motore termina la sua esecuzione nello stato FAIL. 5
  • 16.
  • 17. Capitolo 2 Benchmarks La scelta del benchmark ` un passo importante nell’analisi delle prestazioni di e un software. Le funzionalit` del benchmark, il modo in cui le prestazioni vengono a da esso misurate e il modo in cui i dati finali vengono rappresentati determinano quali parti del sistema ` possibile analizzare, come ` possibile analizzarle attraverso e e lo strumento e come i dati possono essere interpretati e rielaborati in modo che essi abbiano un significato concreto, tale da mettere alla luce le lacune del software esa- minato. Il capitolo ` diviso in due sezioni. La prima descrive brevemente i possibili e profiler adatti ad un’analisi di memoria e velocit` di esecuzione di un’applicazione a Java. Vengono poi confrontati i vari strumenti ed esposte le ragioni che hanno por- tato alla scelta dell’uno anzich´ dell’altro, soffermandosi sulle caratteristiche del e profiler HPROF, che fornisce i dati analizzati nei capitoli successivi. La seconda sezione riguarda invece le teorie di test, essenziali per esaminare il comportamento del sistema attraverso il profiler. La risoluzione delle clausole di Horn attraverso l’interprete tuProlog viene infatti eseguita per una teoria ben precisa, in quanto ogni teoria determina una successione dei cambiamenti di stato della macchina a stati finiti diverso dalle altre e di conseguenza un diverso comportamento del motore tuProlog. Quindi, durante la scrittura delle teorie, si considera che esse devono testare l’interprete in modo tale da poterne analizzare le prestazioni in tutti i possibili impieghi. 7
  • 18. CAPITOLO 2. BENCHMARKS 2.1 Profilers Il profiler ` essenzialmente uno strumento in grado di misurare le performance e e analizzare il comportamento di un certo software durante la sua esecuzione. Il modo in cui questo viene attuato ed il modo in cui i dati collezionati vengono resi disponibili al cliente varia da profiler a profiler. La scelta dello strumento pi` u adatto allo scopo ` dettata non solo da quali variabili si debbano misurare durante e il profiling, ma anche dalla qualit` e quantit` delle informazioni che ` possibile a a e ricavare analizzando i dati forniti. Ad esempio, la scelta di un profiler in grado di misurare, o in grado di fornire dati dal quale sia possibile misurare, la memo- ria allocata da metodi, anche innestati, viene privilegiata rispetto ad un profiler che fornisce solamente i dati relativi alla memoria allocata durante l’esecuzione dell’applicazione. La qualit` delle informazioni ricavate pu` anche essere definita a o come la varianza dei dati misurati dallo strumento in esecuzioni diverse della stes- sa teoria o in esecuzioni della stessa teoria su piattaforme diverse. Maggiore ` lae varianza, minore sar` la qualit` delle informazioni in possesso. Questo problema ` a a e reso evidente dal fatto che i dati ricavati saranno disponibili per future estensioni o modifiche, cosa difficilmente possibile nel caso queste informazioni non siano para- gonabili con quelle misurate su altre piattaforme. Sebbene la risoluzione di questo quesito meriti una discussione a s´ ` possibile ovviare al problema esprimendo i ee tempi di esecuzione dei vari metodi1 con un valore relativo al tempo di esecuzione totale della teoria, anzich´ come valore assoluto. In questo modo si possono avere e informazioni relative a quanto incide un metodo sul tempo di esecuzione totale e questo dato rimane coerente fra diverse esecuzioni dell’interprete in diverse piat- taforme2 . Dato per scontato che lo strumento con cui viene fatto il profiling debba essere in grado di misurare la quantit` di memoria heap allocata e i tempi di esecuzione a Si vedr` pi` avanti che viene assunto come ipotesi il fatto che il tempo di esecuzione totale au 1 della teoria sia dato dalla somma del tempo di esecuzione dei singoli metodi e l’ottimizzazione di uno di essi comporta l’ottimizzazione del tempo di esecuzione totale. Non ` escluso che alcuni sistemi operativi, o alcune implementazioni JVM diverse da quella e 2 della Sun Microsystems, presentino ottimizzazioni che potrebbero far variare le velocit` di ese- a cuzione relative dei vari metodi. Queste variazioni dovrebbero comunque essere ragionevolmente piccole. 8
  • 19. 2.1. PROFILERS di un’applicazione Java, essendo tuProlog scritto interamente in Java, la scelta del profiler viene fatta in primo luogo fra due categorie: i profiler commerciali e quelli non commerciali3 . Data la natura accademica della ricerca si opta per un profiler con licenza di tipo non commerciale. Questa scelta ` dettata dal fatto che utiliz- e zare un software commerciale porrebbe delle barriere economiche ad una futura prosecuzione dell’analisi svolta. Un altro fattore di interesse nella scelta dello stru- mento pi` consono `, come detto in precedenza, la possibilit` di misurare i tempi u e a di esecuzione e la quantit` di memoria allocata dai vari metodi utilizzati durante a la risoluzione di una teoria. Inoltre, osservando l’architettura della macchina a stati finiti, si pu` facilmente intuire che alcuni degli stati in cui il sistema transita o ` vengono utilizzati in maniera predominante rispetto ad altri. E quindi opportuno che la scelta venga indirizzata su un profiler che fornisca anche il numero di chia- mate ad un metodo, in modo da poter analizzare meglio se il sistema spende un certo tempo, o una certa quantit` di memoria, perch´ effettua un numero elevato a e di chiamate a questo o perch´ esso ` computazionalmente complesso. e e Una buona parte dei profiler con le caratteristiche indicate ` basata sull’in- e terfaccia JVM TI (acronimo di Java Virtual Machine Tool Interface) fornita nella piattaforma J2SE della Sun Microsystems a partire dalla versione 1.5. Questa interfaccia provvede un accesso allo stato della JVM da parte di altri strumenti attraverso delle API. All’atto dell’inizializzazione della VM una libreria, scritta in C o C++, viene caricata. Questa pu` invocare chiamate o registrarsi ad eventi, o secondo quanto descritto dall’interfaccia, allo scopo di interrogare la VM riguardo al suo stato. Nei seguenti capitoli i dati sono tutti ricavati dalla libreria HPROF. Questo agente, a differenza degli altri strumenti a disposizione, presenta i risul- tati in maniera piuttosto grezza, senza che vengano elaborati o formattati. Quel che pu` sembrare un difetto, o una mancanza di qualit`, ` in realt` un pregio. o ae a Gli altri profiler infatti, presentando un output pi` o meno elaborato, tendono a u mettere in risalto un aspetto del sistema anzich´ un altro, perdendo informazione. e Con HPROF ` possibile invece elaborare i dati grezzi, in modo tale da mettere in e risalto l’aspetto desiderato. Per software non commerciale si intende shareware o open source. 3 9
  • 20. CAPITOLO 2. BENCHMARKS 2.1.1 Il profiler HPROF HPROF genera le informazioni relative al profiling attraverso le chiamate a JVM TI, le chiamate di ritorno dagli eventi della JVM TI e attraverso l’iniezione di byte code nelle classi caricate dalla VM. Il metodo usato per il profiling dipende dall’opzione con cui viene lanciato HPROF: l’opzione cpu=times inietta il byte code all’ingresso e all’uscita di ogni metodo, l’opzione heap inietta il byte code nel metodo <init> della classe java.lang.Object ed in ogni ‘newarray’ visto all’interno di tutti i metodi, mentre l’opzione cpu=sample utilizza un thread che, svegliandosi ` dopo un determinato intervallo di tempo, campiona lo stack. E possibile utilizzare questo strumento attraverso il comando java -agentlib:hprof[=opzioni] ClasseDaAnalizzare dove la ClasseDaAnalizzare ` la classe alice.tuprolog.Agent con, come primo e parametro, la teoria di test. In particolare, per fare il profiling dei tempi di ese- cuzione e dell’uso dell’heap dell’interprete tuProlog, vengono usati i comandi con le seguenti opzioni: hprof=cpu=times e hprof=heap=sites. Il primo presenta i dati riguardanti al tempo effettivo speso da un metodo in millisecondi, il numero di volte che quel metodo ` stato chiamato da un altro metodo e il trace dello stack e che ha causato quella chiamata. Il secondo comando mostra gli oggetti che sono stati creati durante l’esecuzione del programma. In particolare si possono trovare informazioni riguardanti la memoria occupata e il numero di oggetti vivi in un certo trace, nonch´ la memoria allocata e il numero di oggetti allocati durante l’e- e secuzione dell’intero programma nello stesso trace. Questo permette di analizzare il comportamento del garbage collector durante l’esecuzione della teoria. Inoltre ad ogni oggetto viene associato il trace dello stack che ha generato la sua allocazione in memoria, permettendo di fatto di risalire a quale metodo lo ha istanziato. Uno degli svantaggi di usufruire di un’analisi metodo a metodo, anche se compensato dalla precisione delle misure, ` quello di non poter sfruttare questo procedimento e per teorie il cui calcolo computazionale richieda tempi lunghi, in quanto il pro- filer allunga, anche notevolmente, i tempi di esecuzione. Di questo e dei motivi che hanno portato alla scelta delle opzioni descritte in precedenza viene discusso comunque pi` approfonditamente nei Capitoli 3 e 4. u 10
  • 21. 2.2. TEORIE DI TEST 2.2 Teorie di test Le teorie di test sono una parte del benchmark importante quanto il profiler. Esse infatti determinano il comportamento dell’interprete durante la risoluzione delle clausole e perci` devono essere scelte con cura, in modo tale da permettere o un’analisi il pi` completa possibile. In questa dissertazione vengono presentati u i risultati dei test sul core tuProlog e sulla libreria BasicLibrary, senza testare le librerie aggiuntive come IOLibrary, JavaLibrary o ISOLibrary, anche se queste vengono caricate automaticamente durante l’inizializzazione del motore tuProlog. L’attenzione ` anche rivolta alla scalabilit` del sistema e alcune delle teorie uti- e a lizzate sono scritte in modo tale da permettere vari test sulla scalabilit` senza la a necessit` di pesanti modifiche alla teoria stessa o l’introduzione di nuove teorie. a I risultati trovati in studi precedenti [6], con lo scopo di confrontare tuPro- log con altri interpreti Prolog basati su Java, vennero trovati utilizzando teorie di test note, utilizzate in benchmark atti a misurare la velocit` di risoluzione delle a teorie. Per mantenere una certa continuit` e per poter confrontare i risultati del a lavoro svolto in passato si ` deciso di mantenere, per quanto possibile, alcune delle e teorie gi` utilizzate. Si noti comunque che i sistemi hardware e software su cui a sono stati fatti i test passati e quelli qui descritti sono completamente differenti4 . Questo rende il confronto fra i risultati ottenuti solo indicativo. Tuttavia, alcune delle teorie utilizzate devono essere omesse completamente dall’analisi dei tempi di esecuzione totale (non dall’analisi dei tempi di esecuzione dei vari metodi) per i motivi illustrati nel capitolo 3. Le teorie utilizzate sono: Crypt, Poly, Qsort, Queens, Query, Tak, Einstein’s riddle, Spanning tree e Switch square. Le prime sei fra queste sono teorie che erano gi` state usate come benchmark, mentre le altre sono state introdotte so- a lamente ora. Einstein’s riddle, Spanning tree e Switch square permettono inoltre di ingrandire l’albero di risoluzione delle teorie modificando l’obiettivo. In questo Il sistema su cui sono stati ricavati i risultati antecedenti a quelli qui descritti era equipaggiato 4 con un processore Pentium III 800 MHz, 256 MB di RAM su Windows 2000 e J2SE 1.5.0 09. Il sistema attuale consiste in un processore Pentium IV 2.6 GHz, con 1 GB di RAM su Windows XP Home Edition e J2SE 1.6.0 04. 11
  • 22. CAPITOLO 2. BENCHMARKS modo ` possibile incrementare o diminuire il lavoro svolto dal motore tuProlog e senza modificare la teoria in s´, consentendo di analizzare la scalabilit` del siste- e a ma. Esse svolgono il seguente lavoro: Crypt, data una formula matematica nota, ne cerca la soluzione; Poly dato un polinomio nella forma 1 + x + y + z lo eleva alla decima potenza attraverso la trasformazione simbolica della formula; Qsort riordina una lista di numeri in modo crescente; Queens ` la versione estesa a nove e regine del pi` famoso problema delle 8 regine [1]; Query interroga un database u contenente per ogni nazione la rispettiva dimensione e il numero di cittadini e restituisce, conoscendo gi` il nome di una nazione, quella con la densit` pi` simile a au ad essa; Einstein’s riddle tenta di risolvere un indovinello nel quale viene chiesto chi ` il proprietario di un certo animale data una serie di indizi riguardo a cinque e persone di diversa nazionalit`, residenti in case di colore diverso e con una distinta a preferenza in termini di animali domestici, marche di sigarette e bevande; Span- ning tree data una lista di collegamenti fra nodi, ognuno con un certo peso, trova appunto lo spanning tree [1] di quell’albero; Switch square data una matrice 3x3, i cui valori possono essere vero o falso, tenta di negare i valori posizionati ad una distanza di Manhattan uguale o inferiore ad 1 da una certa cella e, attraverso una sequenza di commutazioni delle celle, cerca di rendere tutti i valori della matrice veri. 12
  • 23. Capitolo 3 Analisi dei tempi di esecuzione In questo capitolo vengono presentati i risultati ottenuti dal profiling delle teorie di test esposte precedentemente. In particolare vengono mostrati quali sono i tempi di esecuzione totali delle teorie e i tempi di esecuzione dei vari metodi utilizzati durante la loro risoluzione. I dati ottenuti vengono poi elaborati in modo da mettere in evidenza quali sono i punti fondamentali su cui il motore deve essere migliorato. Per fare ci` viene prima messa alla prova la scalabilit` del sistema, o a facendo il profiling con teorie via via pi` complesse ed in secondo luogo vengono u costruiti i grafi delle chiamate ai metodi, in modo da evidenziare quali metodi effettuano le chiamate pi` costose da un punto di vista computazionale. u 3.1 Metodo di profiling Come gi` detto, i dati risultanti dal profiling devono fornire il tempo di ese- a cuzione totale della teoria, il tempo di esecuzione dei metodi e, indirettamente, per ognuno di essi, i tempi di esecuzione dei metodi innestati. Ci` ` possibile in oe quanto il profiler HPROF mette a disposizione il trace dello stack che ha generato la chiamata ad un particolare metodo, oltre ovviamente al tempo di esecuzione del metodo (mostrato come percentuale sul tempo di esecuzione totale) e al numero di volte in cui ` stato chiamato. Il comando utilizzato per fare ci` ` il seguente e oe java -agentlib:hprof=cpu=times alice.tuprolog.Agent teoria.pl 13
  • 24. CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE dove la classe Agent, contenuta nel package alice.tuprolog, ` uno strumento che e accetta come parametro una teoria Prolog scritta in un file di testo e, dopo aver tentato di risolverla, stampa sullo standard output il risultato della valutazione. tuProlog permette di valutare una teoria in altri tre modi: lanciando un’interfaccia grafica ed inserendo la teoria in un’apposita TextBox, in un ambiente interattivo attraverso la classe alice.tuprologx.ide.CUIConsole oppure istanziando un oggetto Prolog in una classe Java. Il metodo utilizzato, a differenza degli altri, permette per` di isolare il motore tuProlog, in modo da non dover estromettere dal profiling o i dati non dovuti alla risoluzione, come ad esempio l’istanziazione della GUI. Per misurare il tempo di esecuzione in modo ottimale il file teoria.pl viene costruito in modo da separare tre diversi processi che avvengono durante la riso- luzione della teoria: l’inizializzazione del motore e il caricamento delle librerie1 , la lettura delle clausole di Horn e la risoluzione vera e propria. Vengono quin- di dapprima misurati i tempi di esecuzione della lettura della teoria assieme alla sua risoluzione risolvendo un certo obiettivo2 . Successivamente lo stesso obiet- tivo viene risolto per undici volte e viene sottratto il tempo di esecuzione pre- cedentemente trovato. Questo ` equivalente a misurare undici volte il tempo di e esecuzione dell’obiettivo pi` una volta il tempo di lettura della teoria per poi sot- u ` trarlo. E inoltre necessario evitare di misurare il tempo di creazione della JVM e per fare ci` viene scritta un’ulteriore teoria in cui viene usato il metodo Ja- o va java.lang.System.currentTimeMillis prima e dopo l’esecuzione dell’obiettivo. Il codice Prolog della teoria indicata risulta il seguente: time(T) :- class(’java.lang.System’) <- currentTimeMillis returns T. go(File) :- time(A), consult(File), time(B), C is B-A, print(C). dove File rappresenta il nome completo del file di testo in cui ` contenuta la e teoria da valutare. All’interno di questo file sono contenute le seguenti clausole, le quali permettono di valutare il tempo di lettura ed esecuzione: I tempi in cui questi processi avvengono sono dovuti alla JVM e non al motore tuProlog in 1 s´. e Per diminuire la dispersione delle misure ` stato misurato dodici volte il tempo di esecuzione e 2 dell’obiettivo e sottratto il valore massimo e minimo trovato. Il tempo di esecuzione ` la media e dei valori rimanenti. 14
  • 25. 3.2. TEMPI DI ESECUZIONE DEI METODI :- solve(goAndRepeat). :- solve(go). goAndRepeat :- goN(11). go :- goal(). goN(0). goN(Z) :- goal(), W is Z-1, goN(W). dove goAndRepeat risolve undici volte l’obiettivo goal(). 3.2 Tempi di esecuzione dei metodi Nonostante il metodo java.lang.System.currentTimeInMillis restituisca un tem- po in millisecondi, la granularit` del valore dipende dal sistema in cui ` ospitata a e la JVM e potrebbe essere maggiore di 1 ms. Nel sistema in cui sono avvenute le misure non ` stato possibile misurare intervalli di tempo minori a 15 ms, il che e fa pensare che lo stesso valore corrisponda alla granularit` del sistema. Questo a ha reso impossibile un’apprezzabile misurazione delle teorie Crypt, Poly, Qsort, Queens e Query in quanto i tempi misurati contengono un errore sulla misura troppo elevato. Teoria Tempo di esecuzione (ms) Errore relativo % Crypt 1669 179,75 Einstein’s riddle 114598 2,62 Poly 31 9677,42 Qsort 671 447,09 Queens 2574 116,55 Query 312 961,54 Spanning tree 18034 16,64 Switch square 93787 3,20 Tak 105721 2,84 Tabella 3.1: Tempi di esecuzione per cento risoluzioni e errore relativo calcolato per una singola esecuzione. Dalla Tabella 3.1 si evince chiaramente che la misurazione dei tempi di let- tura della teoria e risoluzione dell’obiettivo non possono essere misurati con una 15
  • 26. CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE buona precisione. Nella Tabella 3.2 vengono quindi illustrati i tempi delle teorie Einstein’s riddle, Spanning tree, Switch square e Tak i quali hanno errori relativi ragionevolmente contenuti. La distinzione fra le due modalit` di esecuzione ha a lo scopo di mettere in luce quali sono le parti del motore tuProlog che possono causare una degradazione delle performance. Teoria Lettura esec (ms) Esec (ms) Esec/Lettura esec % Einstein’s riddle 13807 13331 96,6 Spanning tree 2216 1868 84,3 Switch square 10110 9628 95,2 Tak 11373 10797 94,9 Tabella 3.2: Tempi di lettura ed esecuzione. Si pu` quindi affermare che il tempo di lettura risulta essere all’incirca costante al o variare della teoria3 . I metodi coinvolti nella risoluzione dell’obiettivo occuperan- no la maggior parte del tempo di esecuzione totale e questo permette un profiling senza distinguere fra lettura ed esecuzione, come ` stato fatto fin d’ora, dato che e non valutare i metodi coinvolti durante la prima fase non comporta una perdita di informazione significativa. Di seguito, nella Tabella 3.3, vengono presentati i risultati del profiling, ese- guiti nei modi descritti precedentemente. Per ogni teoria ci si limita a presentare i risultati di quei metodi il cui tempo impiegato a terminare4 ` superiore o uguale e al 2% del tempo di esecuzione totale. Nel caso di Spanning tree, la teoria pi` lunga, il numero di righe che il motore deve leggere u 3 ` 186, mentre nel caso di Tak, quella pi` corta, il numero di righe ` 29. e u e Il tempo impiegato ad un metodo per terminare non comprende il tempo impiegato ai metodi 4 innestati in esso ad essere eseguiti. 16
  • 27. 3.2. TEMPI DI ESECUZIONE DEI METODI Teoria Nome metodo Tempo esec % N. chiamate java.lang.Object.wait 41,65 2 Crypt java.lang.AbstractStringBuilder.append 2,27 60583 alice.tuprolog.Var.occurCheck 21,35 14909053 alice.tuprolog.Struct.getTerm 14,24 30803506 alice.tuprolog.Var.free 6,01 4676006 java.util.AbstractList$Itr.next 4,60 4251755 alice.tuprolog.Struct.getArity 3,9 14871224 E.’s riddle java.util.ArrayList.get 3,82 5599360 alice.tuprolog.Var.unify 3,59 2488524 alice.tuprolog.Struct.unify 3,54 2482605 java.util.AbstractList$Itr.hasNext 3,49 4998320 java.util.ArrayList.add 3,27 5000191 alice.tuprolog.Var.getTerm 2,53 9374073 java.lang.AbstractStringBuilder.append 5,01 34179 java.io.StringReader.read 3,59 24662 alice.tuprolog.Tokenizer.readNextToken 3,12 8815 java.lang.StringBuffer.append 2,96 32544 Poly alice.tuprolog.Tokenizer.readToken 2,92 21835 java.io.StreamTokenizer.nextToken 2,21 17063 alice.tuprolog.Struct.toString 2,21 1986 java.io.StreamTokenizer.read 2,12 24662 alice.tuprolog.Var.occurCheck 3,65 24612 java.lang.AbstractStringBuilder.append 3,58 37404 Qsort alice.tuprolog.Struct.getTerm 3,28 65039 java.lang.StringBuffer.append 2,22 35912 java.io.StringReader.read 2,05 22652 Queens java.lang.Object.wait 36,27 2 java.lang.AbstractStringBuilder.append 3,9 34855 java.io.StringReader.read 2,73 24285 Query alice.tuprolog.Tokenizer.readNextToken 2,29 8534 alice.tuprolog.Tokenizer.readToken 2,23 21002 17
  • 28. CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE java.lang.StringBuffer.append 2,13 30505 java.lang.Object.wait 28,19 6 alice.tuprolog.Var.occurCheck 4,88 531993 alice.tuprolog.Struct.getTerm 4,24 1453666 alice.tuprolog.Var.unify 3,82 546668 S. tree alice.tuprolog.Var.free 2,80 451853 java.util.ArrayList.<init> 2,57 732603 alice.tuprolog.Struct.unify 2,48 295052 alice.tuprolog.Var.getTerm 2,26 1506972 alice.tuprolog.Term.match 2,01 128442 alice.tuprolog.Var.unify 7,95 3632513 alice.tuprolog.Struct.unify 7,92 2719626 alice.tuprolog.Var.free 4,70 2522186 java.util.AbstractList$Itr.next 4,13 2415736 java.util.ArrayList.get 3,99 3694306 alice.tuprolog.Int.unify 3,42 1849876 alice.tuprolog.Struct.copy 3,39 1492772 S. square alice.tuprolog.Var.getTerm 3,22 6554696 java.lang.AbstractStringBuilder.append 3,14 1691076 java.util.AbstractList$Itr.hasNext 3,02 2821175 java.util.ArrayList.add 2,83 2475406 alice.tuprolog.Var.copy 2,77 1118445 java.util.IdentityHashMap.get 2,35 1118445 alice.tuprolog.Var.rename 2,18 561971 java.lang.StringBuffer.append 2,00 1677681 alice.tuprolog.Var.unify 5,76 3065460 alice.tuprolog.Var.free 3,74 2081312 java.util.ArrayList.<init> 3,25 3259113 java.util.AbstractList$Itr.hasNext 3,17 3194571 java.lang.AbstractStringBuilder.append 3,04 1947463 java.util.AbstractList$Itr.next 2,78 1823163 Tak java.util.ArrayList.get 2,65 2716581 alice.tuprolog.Var.getTerm 2,60 6292230 18
  • 29. 3.2. TEMPI DI ESECUZIONE DEI METODI alice.tuprolog.Var.copy 2,47 1193928 java.util.AbstractList$Itr.<init> 2,35 3388196 java.util.ArrayList.add 2,23 2210364 alice.tuprolog.Var.rename 2,13 645368 alice.tuprolog.Int.unify 2,12 1355254 Tabella 3.3: Analisi dei metodi. Come si pu` notare, in tre delle nove teorie, il metodo che impiega pi` tempo a o u terminare ` java.lang.Object.wait. Questo metodo viene lanciato dalla JVM (nel e caso si tratti del client HotSpot della JVM e l’algoritmo usato sia seriale) e per- mette al garbage collector di ripulire parte dell’heap quando non ` pi` possibile eu promuovere oggetti dallo young generation all’old generation [4]. Una spiegazione pi` approfondita a riguardo viene data nel capitolo seguente. Per tutti gli altri u metodi risulta difficile fare una ragionevole analisi basata su di una singola teo- ria e, come detto nei capitoli precedenti, si deve ricercare un approccio che possa mettere in luce i miglioramenti in un ambito di utilizzo il pi` eterogeneo possibile. u Nella Tabella 3.4 vengono sommati i tempi di esecuzione relativi di tutti i metodi (anche quelli non inclusi nella Tabella 3.3). Nell’aggregare i risultati delle varie teorie ` stato scelto di sommare semplicemente i risultati parziali senza dare alcun e peso ai tempi di esecuzione delle teorie. Infatti, come si pu` vedere nell’analisi o della scalabilit`, modificando l’obiettivo di una teoria, in modo da allungare o ac- a corciare l’albero di ricerca di una soluzione, il tempo per ottenere una risposta, rispettivamente, cresce o diminuisce linearmente con il numero di foglie dell’albero visitate dalla macchina a stati finiti. Tuttavia i tempi di esecuzione relativi dei vari metodi rimangono costanti. Per questo motivo dare un peso a questi tem- pi significherebbe sbilanciare l’analisi complessiva a favore di una teoria anzich´ e un’altra. Per la stessa ragione nella Tabella 3.4 viene omesso il numero di chiamate ai metodi. Sempre dalla Tabella 3.4 si evince che il metodo java.lang.Object.wait ` ancora e quello che occupa la maggior parte del tempo di esecuzione del motore tuProlog. 19
  • 30. CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE Nome metodo Tempo esec % java.lang.Object.wait 12,15 alice.tuprolog.Var.occurCheck 3,70 alice.tuprolog.Struct.getTerm 3,06 alice.tuprolog.Var.unify 3,05 java.lang.AbstractStringBuilder.append 2,82 alice.tuprolog.Var.free 2,61 alice.tuprolog.Struct.unify 2,25 java.util.AbstractList$Itr.next 1,88 java.util.AbstractList$Itr.hasNext 1,80 alice.tuprolog.Var.getTerm 1,72 java.util.ArrayList.get 1,72 java.lang.StringBuffer.append 1,67 java.util.ArrayList.<init> 1,49 java.util.ArrayList.add 1,37 java.io.StringReader.read 1,16 java.util.AbstractList$Itr.<init> 1,08 alice.tuprolog.Tokenizer.readNextToken 1,01 alice.tuprolog.Var.copy 1,01 Tabella 3.4: Analisi dei metodi totale. Eliminando, o limitando, il numero di chiamate ad esso comporterebbe un miglio- ramento del tempo di esecuzione di circa il 12% sul tempo totale5 . Purtroppo, escludendo il metodo Java gi` citato, non esistono situazioni in cui l’utilizzo di a una funzione ` predominante rispetto alle altre, anche se i metodi nella Tabel- e la 3.4 rappresentano circa la met` del tempo di esecuzione totale. Questo dato a indirizza sicuramente ad una pi` attenta analisi di questi metodi. u 3.3 Analisi della scalabilit` a In questa parte della dissertazione viene data una dimostrazione di come la relazione fra numero di stati visitati nell’albero di ricerca e numero di chiamate ai metodi utilizzati sia lineare. Per fare ci` ` opportuno prendere come teoria di rife- oe Questa ipotesi, se pur plausibile, non ` del tutto veritiera. A causa della lentezza del profiler e 5 HPROF non ` stato infatti possibile analizzare teorie di una certa complessit` computazionale e e a il valore di miglioramento potrebbe essere sottostimato. 20
  • 31. ` 3.3. ANALISI DELLA SCALABILITA rimento la teoria Switch square che permette di ingrandire o rimpicciolire l’albero di ricerca solamente modificando l’obiettivo e calcolare anche il numero di stati in cui si deve transitare per trovare una soluzione. La Tabella 3.5 mostra per ogni obiettivo valutato il tempo di esecuzione della teoria6 e i cinque metodi con tempo di esecuzione pi` elevato con il relativo numero di chiamate per quel metodo. u N. stati e Tempo esec (ms) Nome metodo N. chiamate alice.tuprolog.Struct.unify 1947041 alice.tuprolog.Var.unify 2584249 3 + 6! 247837 alice.tuprolog.Var.free 1802505 java.util.ArrayList.get 2639270 java.util.AbstractList$Itr.next 1725777 alice.tuprolog.Struct.unify 3876572 alice.tuprolog.Var.unify 5181011 3 + 2 ∗ 6! 488623 alice.tuprolog.Var.free 3601750 java.util.AbstractList$Itr.next 3449996 java.util.ArrayList.get 5276156 java.lang.Object.wait 2 java.lang.ref.ReferenceQueue.remove 4 alice.tuprolog.Struct.unify 5813154 3 + 3 ∗ 6! 1898223 alice.tuprolog.Var.unify 7768221 alice.tuprolog.Var.free 5398379 java.util.AbstractList$Itr.next 5173233 java.util.ArrayList.get 7911406 Tabella 3.5: Analisi della scalabilit` del motore tuProlog. a La Tabella 3.5, oltre a mostrare la linearit` fra stati visitati e numero di chia- a mate ad un metodo, mostra anche come il tempo di esecuzione risulti lineare in rapporto all’aumentare dei nodi nell’albero di risoluzione. Questo dimostra una buona scalabilit` del sistema fino alla risoluzione dell’obiettivo con 3 + 2 ∗ 6! stati, a mentre le prestazioni degradano nella risoluzione dell’obiettivo con 3 + 3 ∗ 6! stati a causa dell’intervento del garbage collector. Si tenga in considerazione che il tempo di esecuzione ` pregiudicato dal profiler HPROF che e 6 rallenta l’esecuzione di tuProlog. Per questo motivo non deve essere confrontato con quello della Tabella 3.3, ma solamente con quello degli altri obiettivi. 21
  • 32. CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE 3.4 Grafo delle chiamate Con lo scopo di analizzare pi` in dettaglio i singoli metodi con i tempi di esecu- u zione pi` elevati (si veda la Tabella 3.4) vengono esaminate le chiamate ad ognuno u dei metodi stessi. Dai risultati di questa analisi ` possibile comprendere se l’elevato e tempo di esecuzione di una funzione ` dovuto all’implementazione della funzione e stessa oppure all’uso troppo intenso della funzione da parte di altri metodi. Di conseguenza ` possibile orientare la riscrittura del codice in una delle due dire- e zioni. Per lo stesso principio che ha portato all’aggregazione dei risultati parziali delle varie teorie ed esposto durante la discussione sull’analisi della scalabilit`, lo a studio ` stato realizzato esaminando le chiamate complessivamente pi` utilizzate, e u senza dare peso ai tempi di esecuzione delle singole teorie. Per ogni singolo metodo presente nella Tabella 3.4 ` stato esplorato lo stack allo scopo di trovare quale fu e la prima funzione del package alice a generarne l’esecuzione. Questo accorgimento ` dovuto al fatto che solamente il codice dei metodi del package alice pu` essere e o riscritto, quindi le chiamate fra metodi java (senza tenere conto del fatto che sono da considerarsi gi` ottimizzate) non aggiungono informazione all’analisi7 . a Il risultato dello studio ` la Figura 3.1, la quale mostra per ogni metodo, e rappresentato come nodo nel grafo (si faccia riferimento alla Tabella 3.6 per cono- scere a quale metodo corrisponde ogni nodo), quali sono i suoi chiamanti attraverso una freccia entrante. Una freccia uscente ed entrante nello stesso nodo indica una chiamata ricorsiva e per ognuna delle frecce viene indicata in quale percentuale un determinato metodo viene eseguito per causa del chiamante sul totale delle chiamate8 . L’unico metodo, inserito nella Figura 3.1, il cui chiamante fa parte del package java ` e 7 java.lang.Object.wait. Vengono visualizzati i chiamanti con percentuali uguali o superiori al 5%. 8 22
  • 33. 3.4. GRAFO DELLE CHIAMATE N. nodo Nome metodo 0 java.io.StringReader.read 1 alice.tuprolog.Var.unify 2 java.util.ArrayList.add 3 alice.tuprolog.Var.getTerm 4 alice.tuprolog.Struct.unify 5 alice.tuprolog.Var.occurCheck 6 alice.tuprolog.Var.copy 7 alice.tuprolog.Struct.getTerm 8 alice.tuprolog.Tokenizer.readNextToken 9 java.util.AbstractList$Itr.hasNext 10 alice.tuprolog.Var.free 11 java.lang.Object.wait 12 java.util.ArrayList.get 13 java.util.AbstractList$Itr.<init> 14 java.util.AbstractList$Itr.next 15 java.lang.StringBuffer.append 16 java.lang.AbstractStringBuilder.append 17 java.util.ArrayList.<init> Tabella 3.6: Associazione fra il numero identificativo di un nodo nella Figura 3.1 e il metodo che esso rappresenta. 23
  • 34. CAPITOLO 3. ANALISI DEI TEMPI DI ESECUZIONE ClauseStore.deunify Int.unify 36 11 100 60 9 SubGoalTree.addChild 0 1 2 61 18 Int.unify 13 14 18 40 StateRuleSelection.doJob 25 7 Term.match 3 4 5 24 85 48 11 10 68 99 Tokenizer.readToken 99 Struct.copy 6 7 8 13 Term.match Struct.copy 9 75 14 100 71 java 15 StateBacktrack.dojob ClauseStore.deunify 7 9 10 11 Cl au se St or e.r eu n ify 18 6 50 75 12 ClauseStore.deunify java 15 5 SubGoalTree.getChild 13 ClauseStore.deunify 12 13 14 ClauseInfo.bodyCopy 6 12 9 7 8 ify py Te fy un r o ni m yC eu .re .m od Var.rename Var.rename e.d re at Term.unify b to ch o. or eS nf St us eI se us a au Cl a Cl Cl 42 6 45 7 11 27 Struct.toString Struct.<init> ClauseStore.deunify 17 PrimitiveManager.identify 15 16 17 SubGoalTree.<init> 15 Struct.toString 28 7 6 54 10 5 St Pr at im eR ch at $ iti Struct.<init> er er ul ve at or Op ag eS .m M et an el an m ec er rM r ag Te tio st to er n. gi era .id .g do en Re p J or O tif ob y at er Op Figura 3.1: Analisi delle chiamate ai metodi pi` utilizzati nell’esecuzione delle u teorie. 24
  • 35. Capitolo 4 Analisi dell’utilizzo della memoria Le stesse teorie presentate nel Capitolo 2 vengono ora utilizzate nel profiling del motore con lo scopo di analizzare in quale modo tuProlog sfrutta la memoria heap. Ad una prima discussione sulle modalit` di studio dell’interprete segue la a presentazione dei dati ottenuti, ricavati con il proposito di mettere in evidenza quali sono gli oggetti la cui istanziazione alloca in modo pi` consistente questa u risorsa. A questo fine viene valutata la memoria complessivamente allocata du- rante la risoluzione di una teoria, senza considerare il fatto che il garbage collector libera lo spazio occupato da quegli oggetti non referenziati in un certo momento dell’esecuzione. Infine, come nel capitolo precedente, vengono analizzati quali so- no i metodi che sfruttano maggiormente la memoria, con lo scopo di rendere la riscrittura del codice del motore il pi` circoscritta e proficua possibile. u 4.1 Metodo di profiling Il profiling del motore tuProlog fornisce i dati riguardanti l’utilizzo della memo- ria ed in particolare, per permettere il tipo di analisi introdotta precedentemente, deve mettere a disposizione, per ogni oggetto, i dati relativi alla memoria com- plessiva da esso allocata e il metodo che alloca quel oggetto. Il profiler HPROF permette di ricavare queste informazioni attraverso il seguente comando: java -agentlib:hprof=heap=sites,depth=16 alice.tuprolog.Agent tr.pl 25
  • 36. CAPITOLO 4. ANALISI DELL’UTILIZZO DELLA MEMORIA dove l’opzione hprof=heap=sites visualizza, per ogni metodo incluso in un certo trace dello stack e per ogni oggetto da esso istanziato, i seguenti dati: il tra- ce dello stack che ha generato la chiamata al metodo; la quantit` di memoria totale a istanziata da quel determinato trace insieme al numero totale di istanze create del- l’oggetto in questione. Si deve precisare che HPROF non fornisce la quantit` di a memoria totale occupata da un oggetto, ma bens` la quantit` di memoria occupata ı a da esso escludendo lo spazio utilizzato dalle istanze di oggetti generati al suo in- terno. In questo modo ` possibile affrontare un’analisi classe per classe, separando e ognuna di esse da parte del suo contenuto. Se si volesse studiare quanto una classe sfrutta complessivamente la memoria sarebbe sempre possibile farlo analizzando lo stack. L’opzione depth=16 serve invece ad aumentare la profondit` dello stack vi- a sualizzato in output. Dato che si vogliono studiare quali sono i metodi del package alice che causano l’istanziazione di un oggetto, anche indirettamente, ` ragione- e vole impostare una profondit` del trace uguale a sedici per intercettare tutte le a chiamate, se pur a scapito di un profiling pi` lento. Come spiegato nell’analisi dei u tempi di esecuzione la classe Agent accetta tr.pl come parametro (in questo caso ` il file di testo contente una delle nove teorie gi` presentate) e viene preferita alle e a altre modalit` di esecuzione di tuProlog in quanto permette di analizzare solo la a parte del motore che ha il compito di risolvere la teoria. 4.2 Allocazione degli oggetti in memoria L’allocazione degli oggetti, oltre ad incrementare la quantit` di memoria di cui a tuProlog deve disporre per risolvere una teoria, porta anche ad un aumento dei tempi di esecuzione. Questo avviene sia a causa del tempo necessario alla JVM a creare una nuova istanza di un oggetto in memoria, sia a causa del tempo neces- sario al garbage collector per ripulire lo spazio non referenziato da alcun oggetto. Inoltre l’uso improprio di questa risorsa pu` causare il lancio dell’errore OutOf- o MemoryError1 , interrompendo la risoluzione della teoria. La Tabella 4.1 ` stata costruita sommando le quantit` di memoria istanzia- e a Questo errore viene lanciato da parte della virtual machine nel momento in cui, a causa della 1 mancanza di spazio in memoria, non ` pi` possibile allocare un certo oggetto. eu 26
  • 37. 4.2. ALLOCAZIONE DEGLI OGGETTI IN MEMORIA te dai vari trace per lo stesso oggetto durante l’esecuzione di tuProlog. In questo modo ` possibile valutare complessivamente quanto un determinato oggetto viene e istanziato. Inoltre vengono omessi quegli oggetti che occupano uno spazio in me- moria inferiore al 2% dello spazio totale allocato. Teoria Nome oggetto M. allocata % M. allocata Byte java.lang.Object[] 26,09 1631496 char[] 15,44 965728 java.util.ArrayList 8,54 534280 java.util.AbstractList$Itr 7,68 480040 alice.tuprolog.Struct 5,80 362712 Crypt java.lang.String 4,83 302128 alice.tuprolog.Term[] 4,37 273128 alice.tuprolog.Var 3,85 240728 byte[] 3,71 231960 java.lang.StringBuffer 2,32 145080 java.lang.Object[] 41,27 87078352 char[] 10,15 21423200 java.util.ArrayList 9,92 20935528 java.util.AbstractList$Itr 8,49 17917864 alice.tuprolog.Var 3,88 8191384 E.’s riddle alice.tuprolog.Struct 3,26 6870200 java.util.AbstractList$ListItr 3,22 6787896 java.lang.String 2,94 6207184 java.util.LinkedList$Entry 2,68 5652544 alice.tuprolog.Term[] 2,41 5087632 char[] 33,16 798736 java.util.LinkedList$Entry 13,36 321784 byte[] 12,04 290000 java.lang.String 6,47 155728 Poly int[] 4,02 96728 alice.tuprolog.Token 3,17 76312 27
  • 38. CAPITOLO 4. ANALISI DELL’UTILIZZO DELLA MEMORIA java.util.regex.Matcher 2,36 56824 alice.tuprolog.Var 2,24 54008 java.lang.Object[] 23,12 649056 char[] 15,02 421856 byte[] 8,63 242384 java.util.ArrayList 6,81 191344 java.util.AbstractList$Itr 5,67 159112 Qsort java.lang.String 5,02 141088 alice.tuprolog.Struct 4,69 131768 alice.tuprolog.Var 3,96 111224 alice.tuprolog.Term[] 3,49 98064 java.util.LinkedList$Entry 2,08 58408 java.lang.Object[] 33,73 3742072 char[] 10,43 1156760 java.util.ArrayList 9,96 1104856 java.util.AbstractList$Itr 8,30 921016 alice.tuprolog.Struct 4,58 508408 java.util.AbstractList$ListItr 3,50 388536 Queens java.lang.String 3,02 335128 alice.tuprolog.Term[] 2,86 316936 java.util.LinkedList$Entry 2,66 294712 alice.tuprolog.Var 2,47 273880 alice.tuprolog.ExecutionContext 2,16 239552 byte[] 2,09 231960 java.lang.Object[] 26,57 647232 char[] 11,27 274544 byte[] 9,52 231960 java.util.ArrayList 9,49 231088 Query java.util.AbstractList$Itr 9,20 223984 java.lang.String 3,99 97192 java.util.LinkedList$Entry 3,95 96160 alice.tuprolog.Struct 2,87 70008 28
  • 39. 4.2. ALLOCAZIONE DEGLI OGGETTI IN MEMORIA alice.util.OneWayList 2,39 58264 java.lang.Object[] 38,19 26544168 java.util.ArrayList 12,70 8831704 java.util.AbstractList$Itr 11,46 7964704 char[] 7,57 5262592 java.util.LinkedList$Entry 4,90 3404920 S. tree alice.tuprolog.Struct 3,05 2122008 alice.tuprolog.Var 2,82 1957752 alice.util.OneWayList 2,67 1856008 java.util.AbstractList$ListItr 2,43 1686392 java.lang.String 2,30 1595608 alice.tuprolog.Term[] 2,25 1563112 java.lang.Object[] 24,74 66566376 alice.tuprolog.Struct 17,78 47833088 char[] 16,87 45410744 alice.tuprolog.Term[] 12,56 33810088 S. square alice.tuprolog.Var 6,66 17926784 java.lang.String 5,05 13602072 java.util.ArrayList 3,78 10162824 java.util.AbstractList$Itr 3,54 9532368 java.lang.StringBuffer 3,32 8947632 java.lang.Object[] 32,60 130756896 char[] 12,92 51823792 java.util.ArrayList 9,75 39111280 java.util.AbstractList$Itr 8,21 32912632 alice.tuprolog.Struct 4,51 18097912 alice.tuprolog.Var 4,38 17576824 Tak java.lang.String 3,88 15560176 alice.tuprolog.Term[] 3,54 14217224 java.util.AbstractList$ListItr 2,57 10326264 java.lang.StringBuffer 2,57 10325736 java.util.LinkedList$Entry 2,32 9301336 29
  • 40. CAPITOLO 4. ANALISI DELL’UTILIZZO DELLA MEMORIA alice.tuprolog.ExecutionContext 2,03 8132024 Tabella 4.1: Analisi degli oggetti utilizzati. Come si pu` osservare, in otto delle nove teorie, l’oggetto pi` utilizzato ` un o u e array di Object. Esso viene utilizzato principalmente nella classe ArrayList per mantenere un buffer nel quale viene memorizzata la lista in questione. Un altro oggetto che compare vistosamente nella tabella ` l’array char[], che viene utilizzato e prevalentemente per memorizzare delle stringhe nelle classi String e StringBuilder (o nella sua versione synchronized StringBuffer). Nel grafo delle allocazioni si pu` o vedere in modo pi` specifico quali sono i metodi che istanziano questi oggetti. u Nella Tabella 4.3 vengono mostrati quali sono gli oggetti complessivamente pi` utilizzati durante la risoluzione delle teorie. Per le stesse ragioni esposte nel- u l’analisi della scalabilit` le varie percentuali di utilizzo della memoria degli oggetti a vengono sommate dando lo stesso peso alle varie teorie, sebbene la quantit` di a memoria totale istanziata da una di esse possa essere diversa da quella istanziata dalle altre. A sostegno di questa tesi, nella Tabella 4.2, vengono elencati i sei og- getti che hanno fatto misurare le percentuali di utilizzo della memoria pi` elevate u durante la risoluzione della teoria Switch square. Le misurazioni sono state fatte per ognuno dei tre obiettivi utilizzati nell’analisi dei metodi, i quali permettono di cercare in 3 + 6!, in 3 + 2 ∗ 6! oppure in 3 + 3 ∗ 6! diversi stati prima di tro- vare la soluzione della teoria. Anche se la precisione dei risultati non rispecchia quella avuta nell’analisi dei tempi di esecuzione, si pu` comunque assumere, con o buona approssimazione, che al variare dell’obiettivo e del numero di stati visitati nell’albero di ricerca la percentuale di spazio allocato in memoria da ogni oggetto, rispetto allo spazio totale allocato, rimane costante. Come detto precedentemente, questo permette di analizzare l’utilizzo della memoria semplicemente sommando i dati contenuti nella Tabella 4.1. 30
  • 41. 4.2. ALLOCAZIONE DEGLI OGGETTI IN MEMORIA N. stati Nome oggetto M. allocata % java.lang.Object[] 24,74 alice.tuprolog.Struct 17,78 char[] 16,87 3 + 6! alice.tuprolog.Term[] 12,56 alice.tuprolog.Var 6,66 java.lang.String 5,05 alice.tuprolog.Struct 23,23 char[] 17,80 alice.tuprolog.Term[] 17,31 3 + 2 ∗ 6! alice.tuprolog.Var 12,60 java.lang.String 10,97 java.lang.Object[] 8,87 alice.tuprolog.Struct 19,12 char[] 18,37 alice.tuprolog.Term[] 13,94 3 + 3 ∗ 6! java.lang.Object[] 9,97 java.lang.String 9,78 alice.tuprolog.Var 9,37 Tabella 4.2: Analisi dell’utilizzo della memoria da parte degli oggetti rispetto all’obiettivo della teoria. Infine, nella Tabella 4.3, vengono esposti i risultati di questa operazione omet- tendo gli oggetti che allocano meno dell’1% della memoria totale istanziata. L’a- nalisi conferma quanto detto precedentemente. Gli oggetti Object[] e char[] sono ancora i pi` utilizzati da parte di tuProlog occupando il 42,11% della memoria u totale impiegata. Inoltre, ricordando che il profiler HPROF non ingloba nella mi- sura della memoria allocata da un oggetto lo spazio occupato da oggetti innestati, ` possibile considerare questi due oggetti istanziati solamente dalle classi Array- e List, String e StringBuffer. Seguendo questa ipotesi le classi String e StringBuffer allocano complessivamente il 20,68% della memoria, mentre la classe ArrayList ne alloca il 35,30%. Sar` quindi importante, al momento di una futura implemen- a tezione del codice, considerare queste tre classi, le quali occupano nell’insieme il 55,98% della memoria totale. 31