pptx - Computation Structures Group

advertisement
Constructive Computer Architecture:
Guards
Arvind
Computer Science & Artificial Intelligence Lab.
Massachusetts Institute of Technology
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-1
Elastic pipeline
f1
f2
f3
x
inQ
fifo1
fifo2
outQ
rule stage1;
if(inQ.notEmpty && fifo1.notFull)
begin fifo1.enq(f1(inQ.first)); inQ.deq; end endrule
rule stage2;
if(fifo1.notEmpty && fifo2.notFull)
begin fifo2.enq(f2(fifo1.first)); fifo1.deq; end endrule
rule stage3;
if(fifo2.notEmpty && outQ.notFull)
begin outQ.enq(f3(fifo2.first)); fifo2.deq; end endrule
Proper use of FIFOs always involves checking
for emptiness or fullness conditions
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-2
Easy mistakes
rule stage1;
if(inQ.notEmpty && fifo1.notFull)
begin fifo1.enq(f1(inQ.first);
inQ.deq; end
endrule
versus
What is the difference?
rule stage1E;
if(inQ.notEmpty && fifo1.notFull)
fifo1.enq(f1(inQ.first);
if(inQ.notEmpty) inQ.deq;
endrule
Guards is an
abstraction to deal
with such
“atomicity” issues
stage1E may dequeue something even though the value
read has not been processed (ie enqueued into fifo1)
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-3
FIFO Module:
methods with guarded interfaces
enab
rdy
n
not empty
rdy
deq
not empty
enab
rdy
first
not full
enq
n
FIFO
interface Fifo#(numeric type size,
type t);
method Action enq(t x);
method Action deq;
method t first;
endinterface
Every method has a guard (rdy wire)
The compiler ensures that an action method is invoked
(en) only if the guard is true. Similarly the value returned
by a value method is meaningful only if its guard is true
Guards make it possible to transfer the responsibility of
the correct use of a method from the user to the compiler
Guards are extraordinarily convenient for programming
and also enhance modularity of the code
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-4
One-Element FIFO
Implementation with guards
September 24, 2014
http://csg.csail.mit.edu/6.175
not empty
enab
rdy
enab
rdy
n
not empty
rdy
deq
not full
enq
n
FIFO
first
module mkCFFifo (Fifo#(1, t));
Reg#(t)
d <- mkRegU;
Reg#(Bool) v <- mkReg(False);
method Action enq(t x) if (!v);
v <= True; d <= x;
endmethod
method Action deq if (v);
v <= False;
endmethod
method t first if (v);
return d;
endmethod
endmodule
L08-5
Elastic pipeline
with guards
f1
f2
f3
x
inQ
fifo1
fifo2
rule stage1 (True); guard
fifo1.enq(f1(inQ.first);
inQ.deq();
endrule
rule stage2 (True);
fifo2.enq(f2(fifo1.first);
fifo1.deq;
endrule
rule stage3 (True);
outQ.enq(f3(fifo2.first);
fifo2.deq;
endrule
September 24, 2014
outQ
When can stage1 rule fire?
- inQ has an element
- fifo1 has space
The explicit guard is true
but the compiler lifts all
the implicit guards of the
methods to the top of the
rule
http://csg.csail.mit.edu/6.175
L08-6
Switch with guards
inQ
redQ
greenQ
rule switch (True);
if (inQ.first.color == Red)
begin redQ.enq (inQ.first.value); inQ.deq; end
else begin greenQ.enq(inQ.first.value); inQ.deq; end
endrule
rule switchRed (inQ.first.color == Red);
redQ.enq(inQ.first.value); inQ.deq;
endrule;
rule switchGreen (inQ.first.color == Green);
greenQ.enq(inQ.first.value); inQ.deq;
endrule;
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-7
GCD module
with Guards
Reg#(Bit#(32)) x <- mkReg(0);
Reg#(Bit#(32)) y <- mkReg(0);
rule gcd (x != 0);
If x is 0 then the rule
if (x > y) begin
cannot fire
x <= x – y; end
else begin
x <= y; y <= x; end
endrule
method Action start(Bit#(32) a, Bit#(32) b) if (x = 0);
x <= a; y <= b; endmethod
method Bit#(32) result if (x = 0);
return y; endmethod
Start method can be invoked only if x is 0
The result is available only when x is 0 is True.
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-8
All methods have implicit
guards
Every method call has an implicit guard
associated with it

m.enq(x), the guard indicated whether one can
enqueue into fifo m or not
Methods of primitive modules like registers
and EHRs have their guards always set to True
Guards play an important role in scheduling; a
rule is considered for scheduling only if its
guard is true (“can fire”)
Nevertheless guards are merely syntactic
sugar and are lifted to the top of each rule by
the compiler
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-9
Guard Elimination
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-10
Making guards explicit in
compilation
Make the guards explicit in every method call
by naming the guard and separating it from
the unguarded body of the method call, i.e.,
syntactically replace m.g(e) by
m.gB(e) when m.gG

Notice m.gG has no parameter because the guard
value should not depend upon the input
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-11
Lifting implicit guards
rule foo if (True);
(if (p) fifo.enq(8)); x.w(7)
All implicit guards are made explicit, and lifted and
conjoined to the rule guard
rule foo if (p & fifo.enqG | !p);
if (p) fifo.enqB(8); x.w(7)
rule foo if (fifo.enqG | !p);
if (p) fifo.enqB(8); x.w(7)
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-12
Make implicit guards explicit
<a> ::= <a> | <a>
| if (<e>) <a>
| m.g(<e>)
m.gB(<e>) when m.gG
| let t = <e> in <a>
<a> ::= <a> | <a>
| if (<e>) <a>
| m.g(<e>)
methods without guards
| let t = <e> in <a>
| <a> when <e> guarded action
September 24, 2014
http://csg.csail.mit.edu/6.175
The new
kernel
language
L08-13
Concrete syntax for
guards
rule x(g);
a
endrule
is the same as rule x (a when g)
method foo(x, y) if (g);
a
endmethod
is the same as
method foo(x, y) (a when g) endmethod
If no guard is explicitly supplied, the guard is
assumed to be True
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-14
Guards vs If’s
A guard on one action of a parallel group of
actions affects every action within the group
(a1 when p1) | a2
==> (a1 | a2) when p1
A condition of a Conditional action only affects
the actions within the scope of the conditional
action
(if (p1) a1) | a2
p1 has no effect on a2 ...
Mixing ifs and whens
(if (p) (a1 when q)) | a2
 ((if (p) a1) | a2) when ((p && q) | !p)
 ((if (p) a1) | a2) when (q | !p)
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-15
Guard Lifting Axioms
without Let-blocks
All the guards can be “lifted” to the top of a rule






(a1 when p) | a2

a1 | (a2 when p)

if (p when q) a

if (p) (a when q)

(a when p1) when p2 
m.gB(e when p)

(a1 | a2) when p
(a1 | a2) when p
(if (p) a) when q
(if (p) a) when (q | !p)
a when (p1 & p2)
m.gB(e) when p
similarly for expressions ...

Rule r (a when p)

Rule r (if (p) a)
We will call this guard lifting transformation WIF,
for when-to-if
A complete guard lifting procedure also requires
rules for let-blockshttp://csg.csail.mit.edu/6.175
September 24, 2014
L08-16
Scheduling with guards
At the top level a guard behaves just like an
“if”
A rule whose guard is False at a given cycle
will result in no state change even if it is
scheduled
The guards of all the rules can be evaluated in
parallel, often with small amount of
computation
The scheduler takes advantage of this fact by
considering only those rules for scheduling in
a given cycle whose guards are True
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-17
Hierarchical scheduling
A method of scheduling is outside-in:
Rules of the outermost modules are scheduled
first, then the rules of subsequent inner
modules are scheduled, as long as they can be
scheduled concurrently with the called
methods
BSV also provides annotation to reverse this
priority on a module basis
It is because of scheduling complications that
current BSV doesn’t allow modular compilation
in the presence of interface parameters
September 24, 2014
http://csg.csail.mit.edu/6.175
L08-18
Download