Kapitel 5.4 - CES
Kapitel 5.4 - CES
Kapitel 5.4 - CES
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Path-Based Scheduling <strong>5.4</strong>-1<br />
Formalisierung des Path-Scheduling-Algorithmus’ <strong>5.4</strong>-2<br />
Kontrollflußgraph<br />
G = ( V, E, v 0 )<br />
1. Kontrollflußgraph extrahieren<br />
2. Kontrollflußgraph in einen azyklischen Kontrollflußgraphen<br />
umwandeln<br />
V – Menge der Operationen<br />
E ⊂ V × V– Menge der gerichteten Kanten<br />
– Anfangsknoten<br />
v 0<br />
e v i v j<br />
3. Pfade berechnen<br />
4. für jeden Pfad 'constraints' berechnen<br />
5. für jeden Pfad 'cut-Intervalle' berechnen<br />
Für jede Kante = ( , ) ∈ Eexistiert eine Bedingung cond ( v i , v j ),<br />
die die Durchführung der Operation v j steuert.<br />
N.B.: G ist im allgemeinen Fall ein zyklischer Graph.– (1)<br />
6. für alle Pfade 'cut-Intervalle' berechnen<br />
7. 'cut-Punkte' für den gesamten Graph bestimmen<br />
8. 'cut-Punkte' für jeden Pfad berechnen<br />
9. Pfade zerlegen<br />
10. Zustände berechnen<br />
11. Zustandsübergänge berechnen<br />
12. Zustandsübergangs-Bedingungen berechnen<br />
Azyklischer Kontrollflußgraph <strong>5.4</strong>-3<br />
Ausgehend von G kann man durch Schleifen-Entfernung einen azyklischen<br />
Graph generieren.<br />
G'<br />
= ( V, E' , L' , V 0 )<br />
V – Operationen<br />
L' – entfernte Kanten<br />
E' – Rest-Kanten<br />
E' ∩ L' = ∅ und E' ∪ L' = E<br />
13. Bedingungen für jede Operation berechnen<br />
V 0 – Anfangsknoten, wobei<br />
V 0 = { V 0 } ∪ { V}<br />
falls ∃v<br />
∈ V ⋅ ( v' , v) ∈ L'<br />
- (2)<br />
d.h. alle Endknoten der entfernten Kante
Beispiel - Spezifikation und Kontrollflußgrap <strong>5.4</strong>-4<br />
Beispiel - Azyklischer Kontrollflußgraph <strong>5.4</strong>-5<br />
entity prefetch is<br />
port (branchpc, ibus : in bit 32;<br />
branch, ire : in bit;<br />
ppc, popc, obus : out bit 32);<br />
1<br />
2<br />
1<br />
architecture behaviour of prefetch is<br />
begin<br />
process<br />
begin<br />
ppc
Pfade des Kontrollflußgraphen <strong>5.4</strong>-6<br />
Pfade und Constraints <strong>5.4</strong>-8<br />
Ein Pfad ist eine Sequenz von aufeinanderfolgenden Knoten. Die<br />
Menge aller Pfade von G’ ist :<br />
1<br />
∪<br />
IP G’ = P v ∈ v0 G’ ( v)<br />
- (3)<br />
2<br />
wobei P G’ ( v)<br />
die Menge aller Pfade ist, die in v beginnen<br />
3<br />
P G’ ( v)<br />
⎧{ v :: rp | rp ∈ P G’ ( v' ), falls ∃v'<br />
⋅ ( vv' , ) ∈E'}<br />
= ⎨<br />
⎩{ [ v]<br />
}, sonst<br />
'::' entspricht der 'cons'-Operation.<br />
– (4)<br />
branch<br />
5<br />
4<br />
6<br />
branch<br />
V0 = {1,7}<br />
Pfade im Beispiel sind:<br />
p 1 (1) = [1,2,3,4,5,6,7,8,9,10]<br />
p 2 (1) = [1,2,3,4,6,7,8,9,10]<br />
p 1 (7) = [7,8,9,10]<br />
7<br />
ire<br />
8<br />
Teilpfade eines Pfades <strong>5.4</strong>-7<br />
9<br />
k<br />
Sei T i ( p)<br />
der Teilpfad<br />
k<br />
T i ([ v1 , v 2 , …, v n ]) = [ v i , v i + 1 ,…<br />
, v ] k<br />
Die Menge aller Teilpfade eines Pfades p ist<br />
⎧ k ⎫<br />
TP( p) = ⎨T i( p)<br />
1 ≤ i ≤ k ≤ len( p)<br />
⎬<br />
⎩<br />
⎭<br />
wobei len(p) die Länge des Pfades p ist.<br />
– (5)<br />
– (6)<br />
10<br />
Ziel des Algorithmus:<br />
Jeder Pfad in minimalen Anzahl von<br />
Zustände zu realisieren unter Beruecksichtigung<br />
der Constraints<br />
mögliche Constraints in jedem Zustand:<br />
• Variablen dürfen nur einmal zugewiesen werden<br />
• E/A Schnittstellen durfen nur einmal gelesen bzw. geschrieben werden<br />
• Jeder funktionale Einheit darf nur einmal benutzt werden<br />
• Maximale Zeitdauer des Zustands kann vorgegeben werden
Integration der Constraints <strong>5.4</strong>-9<br />
Beispiel - Constraints für einen Pfad <strong>5.4</strong>-10<br />
Wenn zwischen Operationen v i und v j auf einem Pfad p ein ’constraint’<br />
entsteht, dann wird er als ein Teilpfad [ v i + 1 , v i + 2 , … , v ] j aufgefaßt,<br />
wobei ( v i , v i + 1 ) ∈ E'<br />
1<br />
2<br />
v i<br />
a = b + c<br />
1 Addierer<br />
3<br />
v i+1<br />
branch<br />
4<br />
v j<br />
d = e + f constraint [v i+1 , ..., v j ]<br />
Der 'constraint' besagt, daß der Pfad vor einem Knoten in diesem<br />
Intervall geschnitten werden muß.<br />
Die Menge aller 'constraints' auf einem Pfad p ist<br />
5<br />
ire<br />
6<br />
7<br />
8<br />
cp ( ) ⊂TP( p)<br />
und<br />
9<br />
die Menge aller 'constraints' in G' ist<br />
C G’ =<br />
{ cp ( ) p ∈ P G’ }<br />
– (7)<br />
10<br />
Constraint 1 Constraint 2<br />
für den Pfad p 1 (1) :<br />
Constraint 1 entsteht weil pc in Knoten 5 und 9 zugewiesen wird<br />
c 1 (p 1 (1)) = [6,7,8,9]<br />
Constraint 2 entsteht zwischen den Knoten 3 und 9 unter der<br />
Annahme das nur ein Addierer existiert<br />
c 2 (p 1 (1)) = [4,5,6,7,8,9]
Intervallgraph eines Pfades <strong>5.4</strong>-11<br />
Beispiel - Interval Graph für einen Pfad <strong>5.4</strong>-12<br />
IG G’ ( p) = ( V IGG’ ( p) , R)<br />
V IGG’<br />
( p) = c( p) ∪ { v ∈ V|<br />
∃v'<br />
· ,( v' , v)<br />
∈ L}<br />
das sind alle ’constraints’ auf dem Pfad p und die Endknoten der<br />
Schleifenabbruchs-Kante<br />
branch<br />
1<br />
2<br />
3<br />
4<br />
( c i , c j ) ∈ R ⇔ overlap( c i , c j ) ∧ ( c i , c j ∈ V IGG’ ( p)<br />
)<br />
–(8)<br />
5<br />
6<br />
Constraint 1<br />
overlap ist ein Prädikat über zwei Pfade und ist definiert wie folgt :<br />
ire<br />
7<br />
8<br />
Constraint 2<br />
overlap ([<br />
],<br />
p) = false<br />
overlap( v::g,<br />
p) = mem( v,<br />
p) ∨ overlap( g,<br />
p)<br />
– (9)<br />
9<br />
10<br />
Constraint 1 Constraint 2<br />
mem ist ein Prädikat, welches das Enthaltensein eines Knotens in<br />
einem Pfad überprüft<br />
1<br />
2<br />
2<br />
mem( v , [ ]) = false<br />
mem( v,<br />
v'::p) = ( v = v' ) ∨ mem( v,<br />
p)<br />
–(10)<br />
5<br />
3<br />
4<br />
1<br />
2<br />
3<br />
3<br />
1<br />
6<br />
7<br />
8<br />
4<br />
5<br />
4 5<br />
9<br />
10<br />
Constraints und Intervallgraph fur ein anderes Beispiel
Cliquen-Partitionierung im Intervallgraph <strong>5.4</strong>-13<br />
Cliquen im Intervallgraph IG G’ ( p)<br />
entsprechen der minimalen Anzahl<br />
von Schnittintervallen in einem Pfad p , wobei alle ’constraints’ eingehalten<br />
wurden.<br />
Cut-Intervallgraph von G’ <strong>5.4</strong>-14<br />
CT G’<br />
= ( V CTG’<br />
, E CTG’<br />
)<br />
V CTG’<br />
= ∪p ∈ P G’<br />
CUT G’ ( p)<br />
cl 2<br />
1 2 3 4 5 6 7 7<br />
8<br />
9<br />
3 2<br />
6 5<br />
cl 1<br />
4 3<br />
5 4<br />
10<br />
11<br />
( tp i , tp j ) ∈ E CTG’<br />
⇔<br />
overlap( tp i , tp j ) ∧<br />
( tp i ∈V CTG’<br />
)∧<br />
( tp j ∈ V CTG’<br />
) ∧<br />
( tp i ≠ tp j )<br />
- (15)<br />
Die Menge der Cliquen<br />
CL G’ ( p) = { cl 1 , …, cl r } ⊂ 2 cp ( )<br />
und cl i ∩ cl j = ∅ fuer i ≠ j<br />
– (11)<br />
Die 'cut-Menge' eines Pfades p ist<br />
∪<br />
CUT G’ ( p) =<br />
cut( cl i )<br />
– (12)<br />
cl i ∈ CL G’ ( p)<br />
wobei cut( cl i ) = cut– points tp<br />
– (13)<br />
∀t ∈ cl p i<br />
und cut_points ist definiert wie folgt :<br />
cut_points ([ ],g)= [ ]<br />
cut_points (v::f,g)= if mem(v, g) then v::cut_points(f,g)<br />
else cut_points(f,g) – (14)<br />
Die Minimierung von 'cuts' über den gesamten Graphen G' wird<br />
durch Cliquen-Partitionierung von CTG' erreicht.<br />
Die Menge der Cliquen :<br />
Analog zu (12) kann man die 'cut-Mengen' bestimmen:<br />
wobei<br />
KL G’<br />
KUT G’<br />
= { kl 1 , …, kl s }<br />
= { kut 1 , …, kut s }<br />
kut i = cut – points t p<br />
t ∈ kl p i<br />
– (16)<br />
– (17)
Beispiel - Interval Graph für G' <strong>5.4</strong>-15<br />
’cut-Punkte’ des Graphen <strong>5.4</strong>-16<br />
1<br />
2<br />
1<br />
2<br />
Mit einer heuristischen Auswahl kann man aus der Menge der Kut-<br />
Intervalle KUT G’ bestimmte Knoten auswählen, die 'cut-Punkte' heißen:<br />
3<br />
3<br />
CP G’<br />
= { cp 1 , …, cp s }<br />
branch<br />
5<br />
4<br />
4<br />
branch<br />
cp i ∈ v,<br />
1 ≤ i ≤ s<br />
– (11)<br />
Für jeden Pfad p ∈ P G’ kann eine Menge von cut-Punkten KP( p)<br />
folgendermaßen<br />
definiert werden :<br />
6<br />
6<br />
kp ∈ KP( p)<br />
⇔ ∃cp i ∈ CP G’ , ( kp = cp i )<br />
– (20)<br />
ire<br />
7<br />
8<br />
ire<br />
7<br />
8<br />
7<br />
8<br />
kp ist der Knoten, an dem die Eingangskante geschnitten werden<br />
muß, so daß der Pfad geteilt wird.<br />
9<br />
9<br />
9<br />
10<br />
10<br />
10<br />
CUT G’ ( p 1 ( 1)<br />
) = {[ 1] ,[ 6, 7, 8, 9]<br />
}<br />
CUT G’<br />
( p 2<br />
( 1)<br />
) = {[ 1] ,[ 4, 6, 7, 8, 9]<br />
}<br />
CUT G’<br />
( p 1<br />
( 7)<br />
) = {[ 7]<br />
}<br />
KUT G’ = {[ 1] ,[ 7]<br />
}
Zerlegung des Pfades <strong>5.4</strong>-17<br />
Zustandsbildung <strong>5.4</strong>-18<br />
Bevor ein Pfad p zerlegt wird, wird eine Hilfsfunktion Htp ( , rp)<br />
definiert.<br />
Diese Funktion liefert einen Teilpfad des Pfades p bis zu einem<br />
’cut-Punkt’ sowie den Rest des Pfades<br />
Htp ( , [ ]) = ( tp ,[ ])<br />
Htp ( , v::rp) = if v ∈ KP( p)<br />
then (tp, v::rp)<br />
else H(tp::v, rp) – (21)<br />
Jetzt wird die Funktion Z zur Zerlegung des Pfades<br />
Z([ ]) = [ ]<br />
p ∈ P G’<br />
definiert<br />
Zv::rp ( ) = { tp} ∪ Z{ rp' } falls H( [ v] , rp) = ( tp, rp' ) – (22)<br />
Jetzt können alle zerlegte Teilpfade in Zuständen zusammengefaßt<br />
werden. Dafür werden Äquivalenzklassen gebildet. Die Teilpfade, die<br />
zu einer Äquivalenzklasse gehören, sind Teilpfade mit den gleichen<br />
Anfangsknoten (d.h. gleiche Anfangsoperation).<br />
wobei<br />
v i ::rp i ≅ v j ::rp j ⇔ v i = v j<br />
v i ::rp i ∈ Zp ( i ) ∧ v j ::rp j ∈ Zp ( j ), p i , p j ∈ P G’<br />
– (24)<br />
S G ist die Zustandsmenge, d.h. die Menge aller Äquivalenzklassen, die<br />
mit ≅ über dem gesamten Kontrollflußgraph G definiert sind.<br />
Für den Zustandsgraphen<br />
Die Menge aller Teilpfade des Graphen :<br />
ZG G<br />
= ( S G , E ZG )<br />
– (25)<br />
Z G’<br />
=<br />
{ Zp ( ) | p ∈ P G’ }<br />
– (23)<br />
gibt es für jedes s ∈ S G einen eindeutigen Anfangsknoten, der<br />
genannt wird.<br />
fst( s)
Zustandsübergäng <strong>5.4</strong>-19<br />
Bedingungen für Zustandsübergänge <strong>5.4</strong>-20<br />
Um einen Zustandsübergang zu ermöglichen, müssen zwischen s i<br />
und s j die Bedingungen über allen Teilpfaden, die von s i nach fst( s j )<br />
gehen, erfüllt werden, d.h. es müssen eine UND-Operation über allen<br />
Bedingungen eines Pfades und eine ODER-Operation über allen Pfaden,<br />
die von s i nach fst( s j ) führen, gebildet werden.<br />
s j<br />
s i<br />
E ZG sind die Kanten des Zustandsgraphen.<br />
Eine Kante zwischen s i , s j ∈ S G existiert, wenn die Knoten s i unds j<br />
durch mindestens eine Kante verbunden sind.<br />
∧<br />
∨<br />
trans( s i , s j ) =<br />
cond( v,<br />
v' ) ∧ cond( last( tp) , fst( s ))<br />
j<br />
∀tp<br />
∈ s i<br />
mem( v,<br />
tp)∧<br />
( last( tp) , fst( s<br />
mem( v’ , tp)∧<br />
j<br />
)) ∈ E<br />
( vv’ , ) ∈ E’<br />
– (27)<br />
Eine Hilfsfunktion, die die letzten Knoten des Teilpfads tp ∈ Z( p)<br />
liefert,<br />
wird folgendermaßen definiert :<br />
last ([ ]) = ⊥<br />
last(v::rp) = if rp = [ ] then v else last(rp) – (26)<br />
alle ausgehenden<br />
Kanten zwischen<br />
s i und s j<br />
die Bedingungen<br />
über jede solche<br />
Kante<br />
Jetzt können die Zustandsübergänge definiert werden<br />
( s i , s j ) ∈ E ZG ⇔ ∃tp<br />
∈ s i . ( last( tp) , fst( s j )) ∈ E,<br />
s i , s j ∈ S G<br />
N.B.: Dadurch, daß E und nicht E' genommen wird und keine si¦sj<br />
Restriktion gemacht wird, sind Schleifen auch mitenthalten.
Bedingungen für Operationen - 1 <strong>5.4</strong>-21<br />
Bedingungen für Operationen - 2 <strong>5.4</strong>-22<br />
Eine weitere Hilfsfunktion, die den Teil eines Teilpfades bis zu einem<br />
Knoten v berechnet, ist die folgende :<br />
until(v’::tp, v) = if v’ = v then [v’] else v’::until(tp, v)– (30)<br />
v<br />
v<br />
s<br />
s j<br />
i<br />
Für jeden Knoten müssen die Bedingungen erfüllt sein.<br />
Eine Funktion, die Wahr wird, wenn der Automat im Zustand s i ist,<br />
wird wie folgt definiert ( s ∈ S G ):<br />
Die Funktion en(v) definiert die Bedingungen für die Operation v :<br />
⎛<br />
⎛<br />
⎞ ⎜<br />
⎜<br />
⎟ ⎜<br />
en( v) = ⎜ on( s i ) ⎟ ∧ ⎜<br />
⎜ ∨ ⎟ ⎜<br />
⎝∀<br />
s i<br />
∈ S<br />
⎠ ⎜<br />
G ⎝<br />
in( v,<br />
s i<br />
)<br />
∨<br />
∧<br />
∀s i<br />
∈S G<br />
mem( u,<br />
until( tp,<br />
v)<br />
) ∧<br />
∀tp<br />
∈ s<br />
mem( u’ , until( tp,<br />
v)<br />
) ∧<br />
i<br />
( uu’ , ) ∈ E’<br />
in( v,<br />
s ) i<br />
⎞<br />
⎟<br />
⎟<br />
cond( u, u' ) ⎟<br />
⎟<br />
⎟<br />
⎠<br />
– (31)<br />
on( s)<br />
⎧ true<br />
= ⎨<br />
⎩ false<br />
- (28)<br />
Eine Hilfsfunktion, die Wahr wird, wenn eine Operation v in einem<br />
Zustand s ∈ S G durchgeführt wird, wird wie folgt definiert :<br />
in( v,<br />
s)<br />
⎧ true<br />
= ⎨<br />
⎩false<br />
wenn der Automat im Zustand s ist<br />
sonst<br />
falls ∃tp ∈ s,<br />
mem( v,<br />
tp)<br />
sonst<br />
- (29)<br />
in allen Zuständen,<br />
in denen v liegt<br />
alle Teilpfade in allen<br />
Zuständen, in denen v liegt<br />
Knoten des Teilpfades,<br />
der in v endet