* paralell assignment problem @ 2005-02-08 3:07 skaller 2005-02-08 14:34 ` Stefan Monnier ` (2 more replies) 0 siblings, 3 replies; 17+ messages in thread From: skaller @ 2005-02-08 3:07 UTC (permalink / raw) To: caml-list Does anyone know how to solve the parallel assignment problem? Name invented by me to describe this problem: x1,x2,x3..xn = e1,e2,e3 .. en where ei might contain the variables xj. (Note = here is assignment). The solution is a sequence of assignments involving only xi, ei, and ti, where ti are temporaries introduced to save the values of the expressions. For example, a solution to x,y = y,x is t = x; x = y; y = t I seek a solution which minimises the number of assignments. Note that the relation i < j == ej doesn't depend on xi is not transitive. This (a) confuses me enough I can't see the solution, and (b) is precisely what allows a temporary to remove a dependence. -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: paralell assignment problem 2005-02-08 3:07 paralell assignment problem skaller @ 2005-02-08 14:34 ` Stefan Monnier 2005-02-08 16:02 ` [Caml-list] " skaller 2005-02-08 17:08 ` skaller 2005-02-08 16:03 ` [Caml-list] " Florian Hars 2005-02-08 16:29 ` Marcin 'Qrczak' Kowalczyk 2 siblings, 2 replies; 17+ messages in thread From: Stefan Monnier @ 2005-02-08 14:34 UTC (permalink / raw) To: caml-list > Does anyone know how to solve the parallel assignment problem? > Name invented by me to describe this problem: > x1,x2,x3..xn = e1,e2,e3 .. en > where ei might contain the variables xj. (Note = here is assignment). > The solution is a sequence of assignments involving > only xi, ei, and ti, where ti are temporaries introduced > to save the values of the expressions. For example, Most ML compilers do this sort of thing to break big blocks of mutually recursive functions into smaller such blocks. The algorithm used is generally to extract the "strongly connected components" of the graph. Google for it and you'll surely find an algorithm. Stefan ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-08 14:34 ` Stefan Monnier @ 2005-02-08 16:02 ` skaller 2005-02-08 18:20 ` Stefan Monnier 2005-02-08 17:08 ` skaller 1 sibling, 1 reply; 17+ messages in thread From: skaller @ 2005-02-08 16:02 UTC (permalink / raw) To: Stefan Monnier; +Cc: caml-list On Wed, 2005-02-09 at 01:34, Stefan Monnier wrote: > > Does anyone know how to solve the parallel assignment problem? > > Name invented by me to describe this problem: > > > x1,x2,x3..xn = e1,e2,e3 .. en > > > where ei might contain the variables xj. (Note = here is assignment). > > > The solution is a sequence of assignments involving > > only xi, ei, and ti, where ti are temporaries introduced > > to save the values of the expressions. For example, > > Most ML compilers do this sort of thing to break big blocks of mutually > recursive functions into smaller such blocks. The algorithm used is > generally to extract the "strongly connected components" of the graph. > Google for it and you'll surely find an algorithm. I'm not sure the problem is quite the same though. Call graphs are transitive: if A calls B, and B calls C, then A calls C. However, 'depends on' is not transitive. Here x,y = y,x x and y are mutually dependent, but in the solution: t = x; x = y; y = t t depends on x, x depends on y, and y depends on t. If the dependency were transitive, y would then depend on x, but it doesn't. That is: the graph of the solution seems strongly connected: T -> X -> Y --+ ^ | +-------------+ however, these are *sequential* and not parallel assignments. A solution using digraph decomposition may well be the right answer, perhaps changing the relation to 'depends on the old value of'. This would break the cycle above (since t has no old value, y now doesn't depend on anything). See another post for an algorithm.. -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-08 16:02 ` [Caml-list] " skaller @ 2005-02-08 18:20 ` Stefan Monnier 0 siblings, 0 replies; 17+ messages in thread From: Stefan Monnier @ 2005-02-08 18:20 UTC (permalink / raw) To: skaller; +Cc: caml-list >> Most ML compilers do this sort of thing to break big blocks of mutually >> recursive functions into smaller such blocks. The algorithm used is >> generally to extract the "strongly connected components" of the graph. >> Google for it and you'll surely find an algorithm. > I'm not sure the problem is quite the same though. > Call graphs are transitive: if A calls B, and B calls C, > then A calls C. Right, but the SCC will do the tail/head part of your algorithm in an "optimal" way, and the strongly connected components can then be cracked open by adding the t = ex ... x = t thingy. Stefan ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-08 14:34 ` Stefan Monnier 2005-02-08 16:02 ` [Caml-list] " skaller @ 2005-02-08 17:08 ` skaller 2005-02-08 18:33 ` Radu Grigore 1 sibling, 1 reply; 17+ messages in thread From: skaller @ 2005-02-08 17:08 UTC (permalink / raw) To: Stefan Monnier; +Cc: caml-list On Wed, 2005-02-09 at 01:34, Stefan Monnier wrote: > > Does anyone know how to solve the parallel assignment problem? > > Name invented by me to describe this problem: > > > x1,x2,x3..xn = e1,e2,e3 .. en > > > where ei might contain the variables xj. (Note = here is assignment). > > > The solution is a sequence of assignments involving > > only xi, ei, and ti, where ti are temporaries introduced > > to save the values of the expressions. For example, Here's the algorithm I have implemented, I believe it works, but I'm not sure it finds the minimal solution. The main difficulty is in step 5. 1. Strip out equations of the form xi = xi since they don't do anything. 2. Create 3 lists: head, middle, and tail. 3. For each assignment in the working set: if the RHS does not depend on a variable in the working set, prepend it to the tail else if no RHS in the working set depends on the LHS variable, prepend it to the head else add it to the middle 4. If we moved any assignment to the head or tail list, set the working set to the middle, and go back to step 3 5. The middle now has the property that for any assignment, there is at least one other assignent such that the RHS of one whch depends on the LHS variable of the other. So pick one assignment x = e out of the middle, create a temporary variable t, prepend t = e to the head list and x = t to the tail list, set the working set to the remaining assignments of the middle. If the working set is empty, the result is the reversed head list concatenated with the tail, otherwise go back to step 3 This algorithm (a) finds an equivalent set of serial assignments, and (b) it is clearly locally minimal in the sense that whenever it introduces a temporary in step 5, there was no alternative but to do so. However it isn't clear (to me) that just picking an arbitrary assignment to split into two using a temporary actually minimises the number of temporaries. -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-08 17:08 ` skaller @ 2005-02-08 18:33 ` Radu Grigore 2005-02-09 7:48 ` Radu Grigore 2005-02-09 9:43 ` Radu Grigore 0 siblings, 2 replies; 17+ messages in thread From: Radu Grigore @ 2005-02-08 18:33 UTC (permalink / raw) To: skaller; +Cc: Stefan Monnier, caml-list On Tue, 08 Feb 2005 09:12:32 -0800 (PST), skaller <skaller@users.sourceforge.net> wrote: > However it isn't clear (to me) that just picking an arbitrary > assignment to split into two using a temporary > actually minimises the number of temporaries. I'm mildly convinced that it works. Imagine a graph where an arrow is drawn from A to B only if A appears in the expression to be assigned to B. You can imagine the process of introducing temporaries as marking a few edges in this graph so that you break all cycles. One marked edge = one temporary. But since no identifier appears more than once on the left side, in this graph the in-degree is at most 1 and each node is part of at most one cycle. >From this it follows that each marked edge breaks at most one cycle. Since all your temporaries break at least one cycle the algorithm should work. -- regards, radu http://rgrig.idilis.ro/ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-08 18:33 ` Radu Grigore @ 2005-02-09 7:48 ` Radu Grigore 2005-02-09 10:11 ` skaller 2005-02-09 9:43 ` Radu Grigore 1 sibling, 1 reply; 17+ messages in thread From: Radu Grigore @ 2005-02-09 7:48 UTC (permalink / raw) To: skaller; +Cc: Stefan Monnier, caml-list On Tue, 8 Feb 2005 20:33:52 +0200, Radu Grigore <radugrigore@gmail.com> wrote: > On Tue, 08 Feb 2005 09:12:32 -0800 (PST), skaller > <skaller@users.sourceforge.net> wrote: > > > However it isn't clear (to me) that just picking an arbitrary > > assignment to split into two using a temporary > > actually minimises the number of temporaries. > > I'm mildly convinced that it works. I was obviously too tired yesterday: there are lots of mistakes in my argument. Actually here is an example on which your algorithm uses more assignments than necessary: a = b+c b = c c = a+b The solution is t = c c = a+b a = b+t b = t -- regards, radu http://rgrig.idilis.ro/ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-09 7:48 ` Radu Grigore @ 2005-02-09 10:11 ` skaller 0 siblings, 0 replies; 17+ messages in thread From: skaller @ 2005-02-09 10:11 UTC (permalink / raw) To: Radu Grigore; +Cc: Stefan Monnier, caml-list On Wed, 2005-02-09 at 18:48, Radu Grigore wrote: > On Tue, 8 Feb 2005 20:33:52 +0200, Radu Grigore <radugrigore@gmail.com> wrote: > > On Tue, 08 Feb 2005 09:12:32 -0800 (PST), skaller > > <skaller@users.sourceforge.net> wrote: > > > > > However it isn't clear (to me) that just picking an arbitrary > > > assignment to split into two using a temporary > > > actually minimises the number of temporaries. > > > > I'm mildly convinced that it works. > > I was obviously too tired yesterday: there are lots of mistakes in my argument. > > Actually here is an example on which your algorithm uses more > assignments than necessary: > > a = b+c > b = c > c = a+b > > The solution is > t = c > c = a+b > a = b+t > b = t That's confirmed, my algorithm produces this: ASG _tmp_a<2009> = (Int::add (f::b, f::c)) ASG _tmp_c<2010> = (Int::add (f::a, f::b)) ASG b<1764> = f::c ASG c<1765> = index_2010 ASG a<1763> = index_2009 However, your solution, whilst correct, breaks one of the rules: one of the RHS is refering to the old value of 'c' using the name 't'. The original rules required only assignments using the original LHS variables, the original RHS expressions, and the temporaries, that is, only permitted buffering the RHS expressions, not old values of variables. Allowing *both* RHS expressions (new values of variables) and LHS variables (old values of variables) makes sense, however, as your example demonstrates. And also seems to make solving the problem harder :) -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-08 18:33 ` Radu Grigore 2005-02-09 7:48 ` Radu Grigore @ 2005-02-09 9:43 ` Radu Grigore 2005-02-09 11:19 ` Radu Grigore 2005-02-09 11:34 ` Pascal Zimmer 1 sibling, 2 replies; 17+ messages in thread From: Radu Grigore @ 2005-02-09 9:43 UTC (permalink / raw) To: skaller; +Cc: Stefan Monnier, caml-list On Tue, 8 Feb 2005 20:33:52 +0200, Radu Grigore <radugrigore@gmail.com> wrote: > On Tue, 08 Feb 2005 09:12:32 -0800 (PST), skaller > <skaller@users.sourceforge.net> wrote: > > > However it isn't clear (to me) that just picking an arbitrary > > assignment to split into two using a temporary > > actually minimises the number of temporaries. > > I'm mildly convinced that it works. OK, I took 1h to think about this problem more carefully. Now I'm almost convinced that it is NP :) I'll use the example given in the previous mail: a = b+c b = c c = a+b We can read the first equation as "a must be computed before b and c". So we can construct a graph whose edges mean "source should be computed before target". In this case it is: a -> b a -> c b -> c c -> a c -> b If this graph has no cycles the problem is simple: just do a topological sort and the problem is solved in O(V+E). If the graph has cycles then we need to break them by introducing temporaries. Without looking at the form of RHS expressions, that is without considering computing an expression partially then we are left with two uses for temporaries: 1. hold the original value of a variable 2. hold the result of an expression and write it later to the destination Point (1) requires one extra assignment, while point (2) requires two extra assignments. The effect is however the same: one of the variable's value can be computed as soon as desired. Therefore we will only use (1). [NOTE that your approach used (2) and hence is clearly sub-optimal]. The effect of (1) (and (2)) on the constructed graph is that all in-edges of a variable are removed. So we have reduced the problem to this: "Given a graph mark as few nodes as possible such that the after removing in-edges of marked nodes we obtain a tree". Now, that looks a lot like SET-COVER. In the example above we have these cycles: 1: abc 2: bc 3: ac The set is {1, 2, 3} and the subsets from which we have to choose are a:{1, 3}, b:{2}, c:{1, 2, 3}. The minimum cover is clearly c:{1, 2, 3} and hence the solution is to create a temporary for the original value of c. After removing all in-edges of c and topologically sorting the graph we get: c, a, b. So this is the order in which we should do the other assignments. Yes -- we reached the correct solution. Now, it looks like that starting from a SET-COVER problem one can build a graph with the right relationship between nodes and cycles and then an assignment problem. I can't give a (semi-)formal argument but I have tried on a few instances and the process of construction seems to be fairly algorithmic (although hard to formalize -- at least in an email -- since I used pictures). This is why I say your problem looks NP. An acceptable algorithm might be this one: 1. detect strongly connected components (optional) 2. within each SCC find all cycles and group them in subsets according to the nodes they have in common 3. within each SCC solve SET-COVER (for cycle sets given by common nodes) 4. sort topologically the graph after removing the in-edges of nodes marked at step 3 Step 2 is clearly exponential in the number of variables (consider a complete graph). For step 3 you probably want to use an approximation algorithm. It looks like there are ones with good complexity (but I do not know them so I can't tell anything about the constants). In any case, have a look at: http://www.nada.kth.se/~viggo/wwwcompendium/node146.html If you use the lg C algorithm (C = cycles) then the overall complexity is something like O(2^V), where V is the number of variables. -- regards, radu http://rgrig.idilis.ro/ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-09 9:43 ` Radu Grigore @ 2005-02-09 11:19 ` Radu Grigore 2005-02-09 11:34 ` Pascal Zimmer 1 sibling, 0 replies; 17+ messages in thread From: Radu Grigore @ 2005-02-09 11:19 UTC (permalink / raw) To: skaller; +Cc: Stefan Monnier, caml-list On Wed, 9 Feb 2005 11:43:34 +0200, Radu Grigore <radugrigore@gmail.com> wrote: > 1. hold the original value of a variable > 2. hold the result of an expression and write it later to the destination > > Point (1) requires one extra assignment, while point (2) requires two > extra assignments. The effect is however the same: one of the > variable's value can be computed as soon as desired. Therefore we will > only use (1). [NOTE that your approach used (2) and hence is clearly > sub-optimal]. One more mistake. Both approaches introduce _one_ extra assignment and the algorithm described subsequently is independent on the choice of (1) or (2). For the problem: a = b+c b = c c = a+b The algorithm says: introduce a temporary for c, and the order is c, a, b. With choice (1) the solution is the one I already wrote. With choice (2) it is: // compute temporaries t = a+b // compute c, a, b (skip c because we have temporary, this is what I missed) a = b+c b = c // use temporaries c = t ... for a total of 4 assignments (same as with choice 1). This is better than the 5 assignments given by your algorithm and it does NOT depend on breaking the rule about using temporaries only to save results of expressions (but not initial values). -- regards, radu http://rgrig.idilis.ro/ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-09 9:43 ` Radu Grigore 2005-02-09 11:19 ` Radu Grigore @ 2005-02-09 11:34 ` Pascal Zimmer 2005-02-09 13:53 ` skaller 1 sibling, 1 reply; 17+ messages in thread From: Pascal Zimmer @ 2005-02-09 11:34 UTC (permalink / raw) To: Radu Grigore; +Cc: skaller, caml-list OK, I think I can add my stone now :) Radu Grigore wrote: > OK, I took 1h to think about this problem more carefully. Now I'm > almost convinced that it is NP :) It is. I will reuse your notations: > I'll use the example given in the previous mail: > a = b+c > b = c > c = a+b > > We can read the first equation as "a must be computed before b and c". > So we can construct a graph whose edges mean "source should be > computed before target". In this case it is: > > a -> b > a -> c > b -> c > c -> a > c -> b > > If this graph has no cycles the problem is simple: just do a > topological sort and the problem is solved in O(V+E). If the graph has > cycles then we need to break them by introducing temporaries. Without > looking at the form of RHS expressions, that is without considering > computing an expression partially then we are left with two uses for > temporaries: > > 1. hold the original value of a variable > 2. hold the result of an expression and write it later to the destination > > Point (1) requires one extra assignment, while point (2) requires two > extra assignments. The effect is however the same: one of the > variable's value can be computed as soon as desired. Therefore we will > only use (1). [NOTE that your approach used (2) and hence is clearly > sub-optimal]. First, a remark here, case (2) can *always* be reduced to case (1). Suppose you are saving the expression for variable a into a temporary variable t, and assign a later when you don't need the old value anymore: ... t <- some expression ... <- ... a ... ... <- ... ... <- ... a ... a <- t ... This can be replaced by the assignments: ... t <- a a <- some expression ... <- ... t ... ... <- ... ... <- ... t ... ... (Of course, you can also do the converse transformation.) Thus, as you noticed, all you have to do is decide for which variables we should keep the old values, and then compute all the expressions with them (using a topological sort of what remains). > The effect of (1) (and (2)) on the constructed graph is that all > in-edges of a variable are removed. So we have reduced the problem to > this: "Given a graph mark as few nodes as possible such that the after > removing in-edges of marked nodes we obtain a tree". That's true. But now, let's make a remark: since the marked nodes have only out-edges, they cannot participate in any cycle anymore. So, in fact, we can also remove their out-edges, which means remove the node completely from the graph. The problem can now be rephrased as: "Given a directed graph, find a minimal set of vertices whose deletion leaves an acyclic graph". To put it another way, "given a directed graph G=(V,E), find a minimal subset of vertices V' such that every cycle of G has a vertex in V'". This problem is known as the minimum feedback vertex set, and (sadly) it is NP-complete: http://www.nada.kth.se/~viggo/wwwcompendium/node19.html#3336 Last, to comment Skaller's last post: skaller wrote: > However, your solution, whilst correct, breaks one of > the rules: one of the RHS is refering to the old value > of 'c' using the name 't'. The original rules required > only assignments using the original LHS variables, > the original RHS expressions, and the temporaries, > that is, only permitted buffering the RHS expressions, > not old values of variables. > > Allowing *both* RHS expressions (new values of variables) > and LHS variables (old values of variables) makes sense, > however, as your example demonstrates. And also seems > to make solving the problem harder :) Actually, they are fully equivalent. If you think about the graph defined above, you want to find the set of variables, for which you will compute their expressions, save them into temporary variables, compute the rest, and affect those variables. This now amounts to deleting *out-edges* for the elected variables in the graph. Now, use the same arguments and you get exactly the same graph problem. To summarize: - build the graph as described by Radu - use an approximation algorithm for a minimum feedback vertex set - compute expressions for variables in this set, and store results in temporary variables - use topological sorting on the subgraph to find a correct ordering for the other variables - assign temporary variables to their final destination Hope this helps... Pascal PS: I am not sure this conversation is much OCaml-related anymore... ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] Re: paralell assignment problem 2005-02-09 11:34 ` Pascal Zimmer @ 2005-02-09 13:53 ` skaller 0 siblings, 0 replies; 17+ messages in thread From: skaller @ 2005-02-09 13:53 UTC (permalink / raw) To: Pascal Zimmer; +Cc: Radu Grigore, caml-list On Wed, 2005-02-09 at 22:34, Pascal Zimmer wrote: > The problem can now be rephrased as: "Given a directed graph, find a > minimal set of vertices whose deletion leaves an acyclic graph". To put > it another way, "given a directed graph G=(V,E), find a minimal subset > of vertices V' such that every cycle of G has a vertex in V'". > This problem is known as the minimum feedback vertex set, and (sadly) it > is NP-complete: > http://www.nada.kth.se/~viggo/wwwcompendium/node19.html#3336 Ah, thanks, it reduces to a known problem. > Last, to comment Skaller's last post: [] > Actually, they are fully equivalent. Your argument is fully convincing, thanks (I'm relieved, since I've already implemented the algorithm :) > Hope this helps... Indeed, thanks to everyone who contributed! > PS: I am not sure this conversation is much OCaml-related anymore... It probably wasn't in the first place, but this list has a lot of friendly people with theoretical knowledge and analytical skills: seemed like a good place to ask. However, the algorithm could be applied in Ocaml in the circumstances which lead me to the problem, namely tail rec-call optimisation. Is Ocaml doing this already? >From the ackermann tests I did it looks like stack frame size is dominant in heavily recursive routines, and the extra variables introduced by a non-optimal tail call are only temporaries, so perhaps it isn't worthwhile, as Marcin suggested, but then I don't know anything about how Ocaml works.. -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] paralell assignment problem 2005-02-08 3:07 paralell assignment problem skaller 2005-02-08 14:34 ` Stefan Monnier @ 2005-02-08 16:03 ` Florian Hars 2005-02-08 17:38 ` skaller 2005-02-08 16:29 ` Marcin 'Qrczak' Kowalczyk 2 siblings, 1 reply; 17+ messages in thread From: Florian Hars @ 2005-02-08 16:03 UTC (permalink / raw) To: skaller; +Cc: caml-list skaller wrote: > Does anyone know how to solve the parallel assignment problem > I seek a solution which minimises the number of assignments. What, in polynomial time? Most of the results seem to require paid subscriptions or a library at hand: http://www.google.com/search?q=%22parallel+assignment+problem%22 But the comp.compilers link seems relevant and points further to [3] Robert G Burger, Oscar Waddell, and R. Kent Dybvig. Register allocation using lazy saves, eager restores, and greedy shuffling. In 1995 ACM Conference on Programming Language Design and Implementation, June 1995, pages 130-138. Available online via ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/pubs/Reg-Alloc-PLDI95.ps.gz which claims NP-completeness for the problem. Yours, Florian. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] paralell assignment problem 2005-02-08 16:03 ` [Caml-list] " Florian Hars @ 2005-02-08 17:38 ` skaller 0 siblings, 0 replies; 17+ messages in thread From: skaller @ 2005-02-08 17:38 UTC (permalink / raw) To: Florian Hars; +Cc: caml-list On Wed, 2005-02-09 at 03:03, Florian Hars wrote: > skaller wrote: > > Does anyone know how to solve the parallel assignment problem > > I seek a solution which minimises the number of assignments. > > What, in polynomial time? Actually total exhaustion may be quite feasible for small numbers of assignments which is typical for many tight loops presented as tail-recursive self calls. In this case 'perfection' is desirable, whereas if there are 20 arguments, 'good enough' is probably good enough.. > But the comp.compilers link seems relevant and points further to > > [3] Robert G Burger, Oscar Waddell, and R. Kent Dybvig. > Register allocation using lazy saves, eager restores, > and greedy shuffling. In 1995 ACM Conference on Programming > Language Design and Implementation, June 1995, pages 130-138. > Available online via > ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/pubs/Reg-Alloc-PLDI95.ps.gz > > which claims NP-completeness for the problem. Ah, section 2.3 suggests 'Greedy Shuffling' is useful. At present my algorithm is picking an arbitrary assignment, but this paper suggests picking the which is depended on most. They claim in only one program, their compiler, did this yield non-optimal results, and in the compiler only in 6 of 20,245 cases, in all of which only one additional temporary was allocated. So, thanks, this seems to be enough to finish of the algorithm with some confidence the results will be good! -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] paralell assignment problem 2005-02-08 3:07 paralell assignment problem skaller 2005-02-08 14:34 ` Stefan Monnier 2005-02-08 16:03 ` [Caml-list] " Florian Hars @ 2005-02-08 16:29 ` Marcin 'Qrczak' Kowalczyk 2005-02-08 17:55 ` skaller 2 siblings, 1 reply; 17+ messages in thread From: Marcin 'Qrczak' Kowalczyk @ 2005-02-08 16:29 UTC (permalink / raw) To: caml-list skaller <skaller@users.sourceforge.net> writes: > x1,x2,x3..xn = e1,e2,e3 .. en > > where ei might contain the variables xj. (Note = here is assignment). If they contain calls to unknown functions, they might depend on these variables indirectly. So I'm not convinced that it's worth to eliminate temporaries in those rare cases when it's possible. After all, people rarely assign the value of a variable to another variable. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] paralell assignment problem 2005-02-08 16:29 ` Marcin 'Qrczak' Kowalczyk @ 2005-02-08 17:55 ` skaller 2005-02-08 18:32 ` Marcin 'Qrczak' Kowalczyk 0 siblings, 1 reply; 17+ messages in thread From: skaller @ 2005-02-08 17:55 UTC (permalink / raw) To: Marcin 'Qrczak' Kowalczyk; +Cc: caml-list On Wed, 2005-02-09 at 03:29, Marcin 'Qrczak' Kowalczyk wrote: > skaller <skaller@users.sourceforge.net> writes: > > > x1,x2,x3..xn = e1,e2,e3 .. en > > > > where ei might contain the variables xj. (Note = here is assignment). > > If they contain calls to unknown functions, they might depend on these > variables indirectly. This is true, and I need to ensure that this doesn't cause a problem, which can be done, for example, by evaluating the call to the unknown function first, and then using that value. In this case, you'd be quite right that subsequent optimisation would probably be worthless (calling a function through a variable in Felix is quite expensive) > So I'm not convinced that it's worth to eliminate > temporaries in those rare cases when it's possible. After all, people > rarely assign the value of a variable to another variable. That may be so, however many function calls are direct, that is, to known functions. In particular tail rec calls typically involve passing 'old value - 1' or something similar where no temporary is required. The actual example which prompted this investigation is ackermann, which has two tail-rec calls: fun ack(x:int,y:int):int => if x == 0 then y + 1 elif y == 0 then ack(x-1, 1) else ack(x-1, ack(x, y-1)) endif ; No temporaries are needed in either tail call, and either order of assignment will work. But my actual code created 2 temporaries for each tail call, unnecessarily. -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Caml-list] paralell assignment problem 2005-02-08 17:55 ` skaller @ 2005-02-08 18:32 ` Marcin 'Qrczak' Kowalczyk 0 siblings, 0 replies; 17+ messages in thread From: Marcin 'Qrczak' Kowalczyk @ 2005-02-08 18:32 UTC (permalink / raw) To: caml-list skaller <skaller@users.sourceforge.net> writes: > fun ack(x:int,y:int):int => > if x == 0 then y + 1 > elif y == 0 then ack(x-1, 1) > else ack(x-1, ack(x, y-1)) > endif > ; > > No temporaries are needed in either tail call, > and either order of assignment will work. > But my actual code created 2 temporaries for each > tail call, unnecessarily. In the implementation of my language Kogut which targets C, on the level I assign argument values to parameter slots (global variables), expressions have already been processed into sequences of statements, such that the remaining expressions contain only variables, constants, and simple operations which don't call unknown code, don't have side effects, don't depend on the time when they are evaluated, and can actually be transformed into C expressions, not C statements. On this level it's clear what expressions depend on which virtual registers. I don't bother with finding the optimal assignment - I just make an easy choice way which generates quite good result in most cases: Positions are generally assigned in order. For each position, if the target of the assignment is used among later source expressions, then a C temporary is introduced and the temporary is assigned from the source expression; otherwise the target is assigned directly (unless it's the same as the source, in which case the assignment is skipped). At the end all temporaries are assigned to their targets. Sometimes this generates more temporaries than would be possible with a different order, but I don't care. The C compiler must still introduce a temporary register for moving between two global variables, so maybe it would generate the same code even if all values were passed through temporaries; I've heard gcc is pretty good in propagating copies. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/ ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2005-02-09 13:53 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2005-02-08 3:07 paralell assignment problem skaller 2005-02-08 14:34 ` Stefan Monnier 2005-02-08 16:02 ` [Caml-list] " skaller 2005-02-08 18:20 ` Stefan Monnier 2005-02-08 17:08 ` skaller 2005-02-08 18:33 ` Radu Grigore 2005-02-09 7:48 ` Radu Grigore 2005-02-09 10:11 ` skaller 2005-02-09 9:43 ` Radu Grigore 2005-02-09 11:19 ` Radu Grigore 2005-02-09 11:34 ` Pascal Zimmer 2005-02-09 13:53 ` skaller 2005-02-08 16:03 ` [Caml-list] " Florian Hars 2005-02-08 17:38 ` skaller 2005-02-08 16:29 ` Marcin 'Qrczak' Kowalczyk 2005-02-08 17:55 ` skaller 2005-02-08 18:32 ` Marcin 'Qrczak' Kowalczyk
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox