Analyzing Stack and Heap
Bounds for Primitive Recursive
Programs in PR

Hume
Kevin Hammond,
Pedro Vasconcelos
, Sun Meng,
Álvaro Rebón Portillo
, Leonid Timochouk
University of St Andrews, Scotland
Greg Michaelson, Robert Pointon, Graeme McHale, Chunxiu Liu
Heriot

Watt University, Scotland
Jocelyn Sérot
LASMEA, Clermont

Ferrand, France
http://www.hume

lang.org
Hume
H
igher

order
U
niform
M
eta

E
nvironment
David Hume
Scottish Enlightenment Philosopher
and
Sceptic
1711

1776
Slide
3
Kevin Hammond, University of St Andrews
Hume Research Objectives
•
Real

Time, Hard Space Functional Programming
–
Including Device Drivers, Derek!
•
Virtual Testbed for Space/Time Cost Modelling
•
Generative, Domain

Specific Language Design
Slide
4
Kevin Hammond, University of St Andrews
Overview
1.
Hume Language Design and Examples
2.
Stack and Heap Usage for Primitive Recursive Programs
1.
Cost Model
2.
Inference Algorithm (Type

and

Effect System)
3.
Results of the Analysis
4.
Conclusions and Further Work
Slide
5
Kevin Hammond, University of St Andrews
Hume Design Domain (1)
Slide
6
Kevin Hammond, University of St Andrews
Hume Design Domain (2)
Slide
7
Kevin Hammond, University of St Andrews
State of the Art...
•
Embedded Systems Engineering
–
big trend to high level software design (UML etc.)
–
80% of all embedded software is now written in C/C++
–
75% of embedded software is delivered late
–
bugs can cost $14,000 each to fix!
•
A Major Problem with C/C++ is Poor Memory Management
–
explicit allocation, deallocation
–
pointer following
–
etc. etc.
•
No Accurate Method for Determining Memory Usage
–
profiling, guesswork(!!), approximation
Slide
8
Kevin Hammond, University of St Andrews
A New Direction?
Slide
9
Kevin Hammond, University of St Andrews
Hume Design Objectives
•
Targets embedded/critical applications
–
Hard real

time target
–
Formally bounded
time and space
–
I/O managed through low

level “ports”/“streams”
»
Memory

mapped, timed, interrupts or devices
–
Asynchronous
concurrency
model (multicore?)
–
Simple, easily costed, exception handling mechanisms
–
Transparent design and implementation:
correctness by construction
–
uses Haskell FFI to allow
external calls
in C/assembler etc.
•
High level of expressiveness/productivity
–
Rule

based system: concise & clear using functional notation
–
Runtime errors reduced by
strong polymorphic types
–
Structured reuse
through
higher order functions
–
Thread management simplified by
implicit concurrency/parallelism
–
Elimination of memory errors through
automatic memory management
Reliability,
Expressibility,
Controllability,
Predictability,
Costability
Slide
10
Kevin Hammond, University of St Andrews
FSA

derived Notation
•
Based on generalised
Mealy
machines (see Michaelson et al. 2003)
•
Boxes
encapsulate a set of rules each mapping inputs to outputs
•
Multiple inputs/outputs are grouped into tuples
•
Sets of boxes are
wired
into static process networks (
automata
)
•
Boxes repeat indefinitely once a result is produced (
tail recursion
)
•
Boxes are
asynchronous
(ignored inputs/outputs)
•
Wires are
single

buffered
box
b ...
match
(patt
11
, ..., patt
1k
)

> (expr
11
, ..., expr
1m
)
 ...
 (patt
n1
, ..., patt
nk
)

> (expr
11
, ..., expr
nm
)
;
Slide
11
Kevin Hammond, University of St Andrews
Declaration & Metaprogramming Layer
Hume Language Structure
Coordination Layer
Expression Layer
Slide
12
Kevin Hammond, University of St Andrews
Expression Layer
•
Purely functional, strict, higher

order, polymorphic, stateless
•
Matches are total
•
Timeouts/space overflows are managed through exceptions
varid expr1 …
exprn

function/constructor application
(expr1, …, exprn)

tuples
< expr1, …, exprn >

vectors (sized)
[ expr1, …, exprn ]

lists (bounded)
let
decls
in
expr

local value declarations
expr
within
cexpr

timeout/space restriction
if
expr
then
expr
else
expr

conditional expression
case
expr
of
matches

case expression
expr :: type

type cast
expr
as
type

type coercion (cost implication)
Slide
13
Kevin Hammond, University of St Andrews
Example: Parity Checker
type
Bit = word 1;
type
Parity = boolean;
parity true = (“true”,true);
parity false = (“false”,false);
box
even_parity2
in
(b::Bit, p::Parity)
out
(show::string, p'::Parity)
match
(0,true)

> parity true
 (1,true)

> parity false
 (0,false)

> parity false
 (1,false)

> parity true;
wire
even_parity2 (comm1, even_parity2.p'
initially
true)
(comm2, even_parity2.p);
comm1
p (true,…)
p’
b
even_parity2
comm2
Slide
14
Kevin Hammond, University of St Andrews
Full Hume
PR

Hume
HO

Hume
FSM

Hume
Hume Language Levels
HW

Hume
Full Hume
recursive functions
recursive data structures
PR

Hume
primitive

recursive functions
primitive

recursive data structures
HO

Hume
higher

order non

recursive functions
non

recursive data structures
FSM

Hume
1st

order non

recursive functions
non

recursive data structures
HW

Hume
no functions
non

recursive data structures
Slide
15
Kevin Hammond, University of St Andrews
Predicting the Cost
?
Slide
16
Kevin Hammond, University of St Andrews
A Type

and

Effect
Space Cost Model
•
Relates language structure to <heap, max stack> usage
–
operational semantics expressed using sequent style
•
Tuned to prototype Hume abstract machine interpreter
–
allows accuracy to be measured
–
can be exploited by compiler
Both heap and stack
can be cleared after
a
single
box step
Derived from
theoretical
work on cost
analysis for parallel
programs
Stack; Heap
Slide
17
Kevin Hammond, University of St Andrews
Sized Types
•
Types are annotated with
sizes
–
magnitude of natural
–
length of a list
•
Sizes can be
weakened
to any greater size
–
defined as a
subtyping relation
–
so
10 :: Nat
11
but not
10 :: Nat
9
–
means unknown size,
greater than
any other size, so
10 :: Nat
–
means undefined size,
less than
any other size
•
Will be used to determine recursion bounds
10 :: Nat
10
[6,1,2] :: [Nat
6
]
3
Slide
18
Kevin Hammond, University of St Andrews
Latent Costs
•
Define costs for functions
•
Allow costs to be captured for higher

order functions
Slide
19
Kevin Hammond, University of St Andrews
Types and Effects for
Stack/Heap Usage
•
Size/Cost Expressions
•
Types and Effects
Slide
20
Kevin Hammond, University of St Andrews
Cost Rules: Basic Expressions
Slide
21
Kevin Hammond, University of St Andrews
Cost Rules: Conditionals/Cases
Slide
22
Kevin Hammond, University of St Andrews
Cost Rules:
Function Applications
Slide
23
Kevin Hammond, University of St Andrews
Cost Rules: Function Decls
Slide
24
Kevin Hammond, University of St Andrews
Cost Inference
•
Restrict cost annotations in types to be variables
•
Separately collect
constraints
on variables
•
So, standard unification can be used on types
•
Constraints must be solved to determine closed costs
Slide
25
Kevin Hammond, University of St Andrews
Cost Inference
•
Restrict cost annotations in types to be variables
•
Separately collect
constraints
on variables
•
So, standard unification can be used on types
•
Constraints must be solved to determine closed costs
Slide
26
Kevin Hammond, University of St Andrews
Solving Recurrences
•
For recursive programs, the effect system generates
recurrence relations on constraints
•
These are solved to give closed forms
–
use e.g. Mathematica, called during cost analysis
–
use an “oracle” of known recurrences
–
write a new recurrence solver
•
Constraints are monotonically increasing
Slide
27
Kevin Hammond, University of St Andrews
Example: Length
•
For the recursive length function
length [] = 0;
length (x:xs) = 1 + length xs;
•
The type inferred is:
length ::
[t7]^x21

{
x19
,
x20
}

>nat^x27,
{
x19
>=7+6*x21,
x20
>=2+4*x21,x27>=x21}
{stack,
heap
}
Slide
28
Kevin Hammond, University of St Andrews
Example: Take
•
For the recursive take function
take n [] = [];
take n (x : xs) =
if n > 0 then (x : take (n

1) xs) else [];
•
The type inferred is:
take
::
nat^x53

{x51,x52}

>[t118]^x56

{x54,x55}

>[t118]^x62,
{x51>=0,x52>=0,x54>=10+9*min(x53,x56),
x55>=7+13*min(x53,x56),x62>=min(x53,x56)}
Slide
29
Kevin Hammond, University of St Andrews
Example: Twice/Map
•
For the Higher

Order twice and map2 functions
twice f x = f (f x);
map2 f [] = [];
map2 f (x:[]) = [f x];
map2 f (x:(y:[])) = [f x,f y];
add1 x = 1+x;
h x = map2 (twice add1) x;
•
The types inferred are:
twice
::
(t21

{x14,x15}

>t21)

{x2,x3}

>t21

{
x4
,
x5
}

>t21,
{x2>=0,x3>=0,
x4
>=6+max(1+x14,1),
x5
>=x15+x15}
map1 ::
(t54

{x62,x63}

>t73)

{x45,x46}

>[t54]^x64

{
x47
,
x48
}

>[t73]^x65,
{x45>=0,x46>=0,
x47
>=6+max(1+max(1+x62,1),2),
x48
>=max(8+x63,3),x65>=1}
add1
::
int

{
x23
,
x24
}

>int,
{
x23
>=7,
x24
>=4}
h
::
[int]^x112

{
x75
,
x76
}

>[int]^x113,
{
x75
>=30,
x76
>=25,x113>=1}
Slide
30
Kevin Hammond, University of St Andrews
Results
!
Slide
31
Kevin Hammond, University of St Andrews
Results
function
heap (est)
stack(est)
heap(GHC

O2)
length: 10
181(181) 72(72)
1632
length: 100
1711(1711)
612(612)
2357
length: 1000
17011(17011)
6012(6012)
15630
length: 10000
170011(170011)
60012(60012)
141626
reverse: 10
381(381)
88(98)
2080
reverse: 100
26862(26862)
810(813)
35395
reverse: 1000
2518512(2518512) 8008(8013)
3051874
twice/map2: 1
25(25)
30(30)
1564
twice/map2: 2
38(38)
30(30)
1592
lift
129(144)
89(89)

Slide
32
Kevin Hammond, University of St Andrews
Results (Pump)
•
Cost model applied to mine drainage example
–
implemented in prototype Hume abstract machine compiler
–
compared with measured dynamic runtime costs
box
heap est
heap actual
stack est
stack actual
pump
47
38
17
17
environ
49
47
29
29
water
54
54
24
24
logger
119
105
39
31
others
115
106
70
70
wires
96
84


totals
480
434
179
171
2.6KB
v. 2.4KB
9%
Slide
33
Kevin Hammond, University of St Andrews
The Reality
!!
Slide
34
Kevin Hammond, University of St Andrews
RTLinux Memory Usage (Pump)
text
data
bss
dec
hex
filename
30146
52
30048
60246
eb56
hume_module.o
Module Size Used by
hume_module 61904 0 (unused)
rtl_sched 43200 0 [hume_module]
rtl_fifo 10016 0 [hume_module]
rtl_posixio 7232 0 [rtl_fifo]
rtl_time 10064 0 [hume_module rtl_sched rtl_posixio]
rtl 27216 0 [hume_module rtl_sched rtl_fifo
rtl_posixio rtl_time]
Slide
35
Kevin Hammond, University of St Andrews
Comparison with Java/Ada
(Pump)
•
Source
–
867 (234) for Java
–
251 (51) for Hume
–
? (206) for Ada
•
Size of object code (byte code)
–
7991 (2003) for Hume
–
18316 (7360) for JVM
–
? (12045) for Ada
•
Memory Requirement
–
9MB
for Java (JVM, MacOSX)
–
60KB (RTLinux, bare RTS), 400KB (MacOSX, normal RTS) for Hume
•
Execution Time
–
Hume is 9

12x faster than the JVM
–
The KVM is 30%

80%
slower
than the JVM
Only one benchmark
shown here
Direct Real

time comparison
requires rewrite to RTSJ
But results have
been repeated
for smaller cases
Slide
36
Kevin Hammond, University of St Andrews
Vehicle Sim. Statistics
Thu Aug 21 19:06:06 BST 2003
Box Statistics:
control: MAXRT = 53120ns, TOT = 1960041024ns, MAXHP = 57, MAXSP = 36
env: MAXRT = 9101600ns, TOT = 1580087776ns, MAXHP = 49099, MAXSP = 129
vehicle: MAXRT = 2973120ns, TOT = 2269933760ns, MAXHP = 49164, MAXSP = 133
Box heap usage: 98440 (99414 est)
Box stack usage: 298 (319 est)
Stream/MIDI Statistics:
output1: MAXRT = 22688ns, TOT = 3188562720ns, MAXHP = 71, MAXSP = 1
...
Slide
37
Kevin Hammond, University of St Andrews
Vehicle Sim. Statistics (2)
Wire Statistics:
control.0: MAX DELAY = 24544ns, MAXHP = 47
env.0: MAX DELAY = 67072ns, MAXHP = 11
vehicle.0: MAX DELAY = 33056ns, MAXHP = 47
vehicle.1: MAX DELAY = 32448ns, MAXHP = 2
vehicle.2: MAX DELAY = 9118688ns, MAXHP = 11
vehicle.3: MAX DELAY = 9135968ns, MAXHP = 2
Total heap usage: 197022 (199078 est)
Total stack usage: 597 (640 est)
Sat Aug 23 06:46:19 BST 2003
Slide
38
Kevin Hammond, University of St Andrews
Related Work (Analysis)
•
Regions (Tofte)
–
explicit labelled memory areas, automatic deallocation
•
Cyclone (Morrissett)
–
C syntax, region inference
•
Sized Types (Hughes & Pareto)
–
properties of reactive systems, progress, not inference, not cost
•
Camelot/GRAIL (Sannella, Gilmore, Hofmann et al.)
–
stack/heap inference from JVM bytecode, parametric costs, tail recursion
•
Worst

Case Execution Time Analysis (Wellings et al)
–
Java/Ada, probabilistic cache/execution costs
Slide
39
Kevin Hammond, University of St Andrews
Conclusions
•
Cost Analysis for
Primitive Recursive, Higher

Order, Polymorphic Functions
–
strict, purely functional notation
–
generates
cost equations
plus recurrences
»
recurrences solved by reference to an
oracle
or external solver
–
soundness results under construction
•
Good Practical Results Obtained in a number of cases
–
no loss of accuracy for non

recursive definitions
–
exact
worst

case solutions obtained for many definitions
–
size

aliasing can cause problems for composing polymorphic definitions
Slide
40
Kevin Hammond, University of St Andrews
Further Work/Work in Progress
•
Modelling
–
soundness proofs
»
under construction
•
extends Hughes/Pareto MML to inference, different cost domain
•
many technical problems solved, some remaining
–
resolve size aliasing problem
–
extend to general data structures
–
application to other language paradigms: non

strict, object

oriented, C/C++
•
Real

Time Models
–
Predictive real

time
models need better hardware (especially cache) models
–
alternative real

time scheduling algorithms should be tried
•
1MEuro Framework VI Proposal (FET

OPEN)
–
with Jocelyn Sérot (LASMEA, France), Martin Hofmann (Ludwigs

Maximilian Univerität,
Germany) and AbsInt GmbH (Saarbrücken, Germany)
Slide
41
Kevin Hammond, University of St Andrews
Recent Papers
Inferring Costs for Recursive, Polymorphic and Higher

Order Functional Programs
Pedro Vasconcelos and Kevin Hammond
To appear in
Proc. 2003 Intl. Workshop on Implementation of Functional Languages (IFL ‘03),
Edinburgh,
Springer

Verlag LNCS, 2004.
Winner of the Peter Landin Prize for best paper
Hume: A Domain

Specific Language for Real

Time Embedded Systems
Kevin Hammond and Greg Michaelson
Proc. 2003 Conf. on Generative Programming and Component Engineering (GPCE 2003
), Erfurt, Germany,
Springer

Verlag LNCS, Sept. 2003.
Proposed for ACM TOSEM Fast Track Submission
FSM

Hume: Programming Resource

Limited Systems using Bounded Automata
Greg Michaelson, Kevin Hammond and Jocelyn Sérot
Proc. 2004 ACM Symp. on Applied Computing (SAC ‘04),
Nicosia, Cyprus, March 2004
The Design of Hume
Kevin Hammond
Invited chapter in
Domain

Specific Program Generation
,
Springer

Verlag LNCS State

of

the

art Survey, C. Lengauer (ed.), 2004
Predictable Space Behaviour in FSM

Hume”,
Kevin Hammond and Greg Michaelson,
Proc. 2002
Intl. Workshop on
Implementation of Functional Languages (IFL ‘02),
Madrid
,
Spain, Sept. 2002,
Springer

Verlag LNCS 2670, ISBN 3

540

40190

3,, 2003, pp. 1

16
Slide
42
Kevin Hammond, University of St Andrews
http://www.hume

lang.org
Hume
H
igher

order
U
niform
M
eta

E
nvironment
David Hume
Scottish Enlightenment Philosopher
and Sceptic
1711

1776
Slide
44
Kevin Hammond, University of St Andrews
Results (Far Lifts)
•
Cost model applied to recursive lifts
box
heap est
heap actual
stack est
stack actual
lift1
939
610
218
206
lift2
939
392
218
152
floors
35
31
21
21
logger
715
261
20
20
schedule
78
70
35
35
totals
2706
1364
512
434
12.8KB
v. 7.2KB
Comments 0
Log in to post a comment