Alan, > Hi Loup > Actually, your last guess was how we thought most of the optimizations would > be done (as separate code "guarded" by the meanings). For example, one idea > was that Cairo could be the optimizations of the "graphics meanings code" we > would come up with. But Dan Amelang did such a great job at the meanings that > they ran fast enough tempt us to use them directly (rather than on a > supercomputer, > etc.). In practice, the optimizations we did do are done in the translation > chain and > in the run-time, and Cairo never entered the picture. > > However, this is a great area for developing more technique for how "math" can > be made practical -- because the model is so "pretty" and "compact" -- and > there > is much more that could be done here.
Here is an old idea I had for a "cache manager" (as described in http://www.merlintec.com/lsi/tech.html): One feature that distinguishes programs by experts from those of novices is the use of caching as a performance enhancement. Saving results for later reuse greatly decreases source code readability, unfortunately, obscuring program logic and making debugging much harder. Reflection allows us to move caching to a separate implementation layer in a cache manager object. So the application can be written and debugged "naively" and, after it works, can be annotated to use the cache manager at critical points to significantly improve performance without having to write a new version. This is only possible because Merlin uses message passing "at the bottom" and includes a reflective access to such a fundamental operation. In other words, user applications are never made up of mainly "big black boxes" which the OS can do nothing about. Even simple math expressions as '(x * 2 ) + y' are entirely built from messages that are (in theory - the compiler actually eliminates most of the overhead) handled by a set of meta-objects. So all that the system has to do when the user annotates an expression as cacheable is to replace the standard send meta-object with one that looks up its arguments in a table (cache) and returns a previously calculated answer if it is found there. Otherwise it works exactly like a normal send meta-object. An example of how this works is in rendering text. A given font's glyphs might be given as sets of control points for Bezier curves describing their outlines plus some "hints" for adjusting these points when scaling. We could then draw a character from a font called myFont on aCanvas with the expression: aCanvas drawPixmap: ((myFont glyphFor: 'a' Size: 12) asVectors asPixmap) This should work perfectly, but will be unacceptably slow. For each time some character must be shown in the display its points must be scaled by the 'glyphFor:Size:' method, then the control points must be rendered as short vectors approximating the indicated Bezier curves ('asVectors') and finally these vectors must be used to fill in a picture ('asPixmap') which can finally simply be blasted on the screen for the final result. By marking each of these messages as cacheable, the next time 'glyphFor:Size:' is sent to myFont with exactly 'a' and 12 as arguments it will return the same list of control points without executing the method again. Sending a cacheable 'asVectors' message to the same list of point as before will fetch the same list of vectors as was created the first time, and sending 'asPixmap' to that results in the same character image without actually invoking the filling method once more. So we have replaced three very complex and slow calculations with three simple table lookups. If you think that even that is too much, you are right. The cached control point lists and short vector lists are not really needed. Unfortunately, the cache manager can do nothing about that, but if the user moves multiply cached expression to their own methods like this: pixmapForFont: f Char: c Size: s = ( (f glyphFor: c Size: s) asVectors asPixmap). .... aCanvas drawPixmap: (pixmapForFont: myFont Char: 'a' Size: 12) Now we can make only the 'pixmapForFont:Char:Size:' method cacheable if we want. This will save the final pixmaps without also storing the intermediate (and useless to us) results. This did involve rewriting application code, but actually made it a little more readable, unlike when caching is "hand coded". > Why can't a Nile backend for the GPU board be written? Did I miss something? As Reuben Thomas pointed it, the needed information is not available. In fact, there was no information at all about the chip until this week, but now we have some 30% (the most important part for porting the basic funcionality of some OS). This is the same issue that the OLPC people had (worse in their case, because people would promise to release the information to get them to use a chip and then just didn't do it). Even dealing with FPGA is a pain because of the secret parts. -- Jecel _______________________________________________ fonc mailing list [email protected] http://vpri.org/mailman/listinfo/fonc
