CCHR: De snelste CHR implementatie
Promotor:
Prof. Dr. Bart Demoen Begeleider:
Dr. ir. Tom Schrijvers
Pieter Wuille
20 december 2006
1 Algemeen Waarom CCHR Structuur
2 Implementatie Mogelijkheden Overzicht
3 Ontwerpbeslissingen Geheugenallocatie Macro’s
4 Performantie GCD Voorbeeld FIB Voorbeeld Primes Voorbeeld 5 Gepland werk
Gepland werk
1 Algemeen Waarom CCHR Structuur
2 Implementatie Mogelijkheden Overzicht
3 Ontwerpbeslissingen Geheugenallocatie Macro’s
4 Performantie GCD Voorbeeld FIB Voorbeeld Primes Voorbeeld 5 Gepland werk
Gepland werk
Waarom CHR in C?
De mogelijkheid om CHR te gebruiken in pure C programma’s Een poging tot CHR heel snel maken (oa. door grote vrijheid in C datastructuren)
De verschillende stappen bij het gebruik van CCHR zijn:
CCHR code
CCHR Compiler C macro’s
C Preprocessor C code
C Compiler Executable
CCHR code
Gewone C broncode
Met “cchr { . . . }” blokken in Deze blokken worden vervangen door C macro’s
1 Algemeen Waarom CCHR Structuur
2 Implementatie Mogelijkheden Overzicht
3 Ontwerpbeslissingen Geheugenallocatie Macro’s
4 Performantie GCD Voorbeeld FIB Voorbeeld Primes Voorbeeld 5 Gepland werk
Gepland werk
CHR Constraints
CHR Constraints zijn ge¨ımplementeerd:
Willekeurige ariteit
Alle C datatypes (behalve arrays) als argumenten Extra parameters voor weergave of voor destructors
voorbeeld
constraint init(int),fib(int,bignum_t) destr(destruct_bignum(&$2));
CHR Rules
CHR Rules zijn ge¨ımplementeerd:
Propagation (K , . . .==>. . .) Simplification (R, . . .<=>. . .) Simpagation (K , . . .\ R, . . .<=>. . .)
voorbeelden
begin @ init(_) ==> fib(0,1), fib(1,1);
triv @ gcd(0) <=> true;
dec @ gcd(N) \ gcd(M) <=> M>=N | gcd(M-N);
Variabelen
Variabelen in CHR Rules zijn geimplementeerd:
Als constraint-argument in head Als lokale variabele in guard Als lokale variabele in body
voorbeelden
con(N) ==> N>0 | cons(N-1);
con(N) ==> int M=N-1, M>=0 | con(M);
con(N) ==> N>0 | int M=N-1, con(M);
Niet-HNF Rules
Het is mogelijk CHR Rules die niet in HNF (Head-Normal Form) staan te gebruiken:
Er kunnen C-expressies als argument voorkomen Een variabele mag meermaals voorkomen Een variabele mag in een expressie voorkomen
voorbeelden
con(0) <=> true;
fib(N,_) \ init(N) <=> true;
fib(N-1,M1), fib(N,M2) ==> fib(N+1,M1+M2);
C statements
Het is mogelijk willekeurige C statements in guard of body te plaatsen:
Moet tussen { . . . }
Bv initialisatie van ingwikkelde argumenten
voorbeeld str(Str1) ==>
char *Str2=malloc(2*strlen(Str1)), { strcpy(Str2,Str1);
strcat(Str2,Str1);
}, dblstr(Str2);
Debug-modus
Er is een debug modus:
Door een optie aan C compiler mee te geven
Print alle constraints, uitgevoerde regels, propagation history toevoegingen, . . . uit
vereist een debug(“printf string”) tag bij alle constraints
Source
CCHR
main lexer & parser
analyse
code generatie
C code
Source
CCHR main lexer & parser
analyse code generatie C code
de main module
Bevat de main() C routine Overloopt alle opgegeven sourcefiles
Vervangt .chr of .cchr door .c voor output
Kopieert input naar output, behalve cchr-blokken
Voor cchr blokken worden lexer, parser, analyser en
code-generator aangeroepen
Source
CCHR main lexer & parser
analyse code generatie C code
de lexer
Geschreven mbv. Flex (die lexer genereert in C)
Herkent operatoren, haakjes, symbolen
Parser vraagt deze ’tokens’ op aan lexer
de parser
Geschreven mbv. Bison (die parser genereert in C)
Herkent regels, code-blokken, argumenten, constraints, . . .
Source
CCHR main lexer & parser
analyse code generatie C code
de analyser
Analyseert output van de parser (abstract syntax tree)
Genereert nieuwe data structuur met expressions, variabelen, constraints, regels, . . . Doet conversie naar Head Normal Form
Analyseert gebruik van variabelen, waar propagation history bij te houden, . . .
Source
CCHR main lexer & parser
analyse code generatie C code
de code-generator
Gebruikt de gegevens gegenereerd door analyser Genereert een aantal macro’s voor elke constraint/regel Voor elke constraint occurrence een macro met code
1 Algemeen Waarom CCHR Structuur
2 Implementatie Mogelijkheden Overzicht
3 Ontwerpbeslissingen Geheugenallocatie Macro’s
4 Performantie GCD Voorbeeld FIB Voorbeeld Primes Voorbeeld 5 Gepland werk
Gepland werk
Geheugenallocatie
Alle ge-malloc()-ed geheugen wordt ge-free()-d
Garbage Collector is niet noodzakelijk, dmv. user-defined destructors
Eventueel kan alternatieve malloc()/free() gebruikt worden (eg. Boehm)
Gebruik van C macro’s:
voordelen
Minder echte code in CCHR compiler zelf (hardcoded) Keuze van eg. datastructuren kan buiten compiler Overzichtelijkere outputcode
Debug-mode door simpel optie meegeven aan C compiler
nadelen
Veel moeilijker locatie van bugs te vinden Macro definities redelijk moeilijk leesbare code
1 Algemeen Waarom CCHR Structuur
2 Implementatie Mogelijkheden Overzicht
3 Ontwerpbeslissingen Geheugenallocatie Macro’s
4 Performantie GCD Voorbeeld FIB Voorbeeld Primes Voorbeeld 5 Gepland werk
Gepland werk
constraint gcd(uint64_t);
triv @ gcd(0ULL) <=> true;
dec @ gcd(N) \ gcd(M) <=> M>=N | gcd(M-N);
Beginnen met: gcd(100000000),gcd(5).
resultaten
implementatie runtime cycles/iteratie swi-prolog 37.1s 4100
cchr 0.08s 8.8
Java heeft geen tail recursion → stack overflow
typedef struct { mpz_t v; } bigint_t;
cchr {
constraint fib(int,bigint_t) destr(mpz_clear($2.v));
constraint init(int);
begin @ init(_) ==> bigint_t Z=, bigint_t Y=, { mpz_init_set_si(Z.v,1);
mpz_init_set_si(Y.v,1);
}, fib(0,Z), fib(1,Y);
calc @ init(Max), fib(N-1,M1), fib(N,M2) ==> N<Max | bigint_t Sum=, {
mpz_init(Sum.v);
mpz_add(Sum.v,M1.v,M2.v);
}, fib(N+1, Sum);
fini @ init(_) <=> true;
}
Beginnen met: init(7499).
Versie 2 gebruikt:
fini @ fib(Max,_) \ init(Max) <=> true;
in plaats van:
fini @ init(_) <=> true;
resultaten
implementatie runtime(v1) runtime(v2)
swi-prolog 740s 294s
jchr 4.56s 0.149s
cchr 2.06s 1.22s
cchr (no hist) - 0.505s
constraint candidate(int),prime(int);
candidate(1) <=> true;
candidate(N) <=> prime(N), candidate(N-1);
prime(Y) \ prime(X) <=> (X%Y)==0 | true;
Beginnen met: candidate(23000).
resultaten
implementatie runtime swi-prolog 330s
jchr 48.5s
cchr 8.9s
1 Algemeen Waarom CCHR Structuur
2 Implementatie Mogelijkheden Overzicht
3 Ontwerpbeslissingen Geheugenallocatie Macro’s
4 Performantie GCD Voorbeeld FIB Voorbeeld Primes Voorbeeld 5 Gepland werk
Gepland werk
Gepland werk
Built-in constraints (mbv. union find) & reactivatie Meer datastructuren (eg. hashtables)
Functies om over constraint store te itereren Meer voorbeelden uitwerken en testen
Parameters bij rules (pragma’s, eg. “passive”) Meer optimalisaties
Nog vragen?