From: Robert E. <pa...@tu...> - 2003-02-18 16:06:34
|
Hello. This is my first posting to this list, reflecting my intentions to implement my first contributions to this project. In my former life, I was a display list expert at a major computing corporation; now, through the graces of my new employer (Tungsten Graphics) I am eagerly preparing to devote some of my efforts to bringing new functionality to Chromium. This has been preliminarily reviewed by my co-workers; I would like to now offer it to a more global audience, for inspection and comments. Thanks for your time and attention... Bob Ellison Tungsten Graphics --------------------------------------------------------------- Problem Statement: While using the "tilesort" SPU, all display lists are sent to all servers as they are created; in that way, they are treated like state, while display list references (i.e. glCallList & glCallLists) are treated like primitives. Unfortunately, this distribution of display lists can saturate the network quickly; and in the general case, a particular display list may not be needed by a particular server (i.e. if the bounds of the rendered display list all fit in one tile being rendered by a single node, it is inefficient to send that display list to all nodes). Proposed Solution: In the client library (in a new SPU based on "tilesort"), manage display lists and content as they are created. At reference time, determine which nodes need to know about the display list (by bounding box calculations), and, if that node hasn't seen the display list before, send the display list (and all sub-display lists, i.e. display lists referenced within the top-level display list itself). Design: Client-managed Display Lists Based on: Tile Sort SPU Configuration: - CR_SHARED_DISPLAY_LISTS should be *off* for "normal" uses, or we run the risk of breaking a distributed application that relies on one node to create display lists and another node to use them. A warning will be issued at MakeCurrent if this is discovered. New Configuration Variables: - none New State, per client: - managedDisplayLists: a set (default empty) of struct { displayListIdentifier: the name of the associated DL acquaintedServers: a set of Chromium servers that know about this DL (i.e. the display list has already been created on each server in this list) retainedContent: a set of content buffers that can be sent to a server to create the display list there } Override these functions: glNewList: should invoke a packer that saves all the DL content buffers without sending any to the Chromium server. glEndList: will add a new entry to the managedDisplayLists set, with: displayListIdentifier = identifier provided in glNewList acquaintedServers = empty set retainedContent = the list of content buffers /* helper function for glCallList; returns true if the * managedDisplayList record can be deleted, because all * servers have a copy */ SendToServer(identifier, server) { get the managedDisplayLists record for the display list identified with "identifier" if the given server is not in the acquaintedServers list { send the retained content to the server, to create the display list on that server add the server to the acquaintedServers list /* make sure all sub-display lists are also sent. A mechanism to avoid an infinite loop if a recursive network is found will be implemented, but is not included in this design */ for each display list referenced by this display list { SendToServer(associated identifier, server) } if (all known servers now have a copy of this DL) { return true } } return false } glCallList(identifier) { serverList = the list of servers to which this glCallList should be sent, based on bounding boxes and extents if (identifier is in the managedDisplayLists set { for each server in serverList { knownEverywhere = SendToServer(identifier, server) /* If the DL is known everywhere, the client no longer * needs to manage it */ if (knownEverywhere) { delete the managedDisplayLists record break } } } for each server in serverList { send a glCallList reference to that server } } glCallLists: similar to above glDeleteLists: delete associated managedDisplayList records pass through the glDeleteLists call /* Future: allow the use of the callback to * define the DL, instead of relying on retained * content */ Possible future work: - Client-side management of display list proxies in addition to full display lists. (To "proxy" a display list, the application identifies a callback function that will be used to create display lists on demand. The application may then use glCallList et al. to invoke display lists without explicitly defining them first; the client-side display list manager will invoke the callback when needed.) The advantage to the application is that the client-side DL manager need not retain potentially large pools of DL content, which typically duplicates content storage in the application itself. This could be useful to reduce resource contention at application nodes. - retention aging. Every time a managed display list is referenced without having to recreate the DL on some server, its "age" increases. (Every time it is sent to a new server, its age is reset to 0.) When it reaches a threshold, the client library can delete its retained content, in the assumption that the display list has been sent to every server that it will ever be sent to. (This should not be allowed unless a definition callback is defined, just in case the client library is wrong in its assumption.) This again can reduce memory usage and resource contention at the client nodes, by allowing the retained display list content to be freed in some cases that would otherwise have forced it to be retained indefinitely. - management of display lists created with glXUseXFont. - networked display list management; an application node may tell a server that it knows how to create a display list, without explicitly sending the content quite yet. Later, if another node sends a reference to such a display list, the server can send a query back to the original node asking it to create the display list. This allows client-side display list management to be used even in an environment where one networked node creates shared display lists to be used by other nodes, but at the cost of requiring a server-client round-trip. |
From: Sean A. <sea...@ll...> - 2003-02-24 22:54:40
|
Robert Ellison wrote: > In the client library (in a new SPU based on "tilesort"), manage display > lists and content as they are created. At reference time, determine > which nodes need to know about the display list (by bounding box > calculations), and, if that node hasn't seen the display list before, > send the display list (and all sub-display lists, i.e. display lists > referenced within the top-level display list itself). This sounds good. I think that this is very much needed to make display lists "just work" correctly. Most of your future work has to do with managing the memory content of retaining display lists. I have one more suggestion. An application might signal (through a parameter call) to client library that it is to turn on/off management of the following display lists. Any display lists that are unmanaged are sent in broadcast mode, as they are done currently in Cr. In this way, the application can, in effect, tell the client library that it is going to take care of the management itself, providing a way to "age" a list manually. -Sean __ sea...@ll... |
From: Mike H. <mho...@gr...> - 2004-10-27 03:30:02
|
I see you've updated the IB stuff, at least the makefiles, to use the TopSpin stack. This is a really bad idea. You'll want to run the OpenIB gen1 stack or better yet the Mellanox HPC Gold stack which is public and "easy" to use. The later is now seemingly the standard stack until the OpenIB gen2 stack cleans up and goes for Linux kernel inclusion. The IB (VAPI) code was fragile already. SDP was better off, but is only known to work, albeit hackily, with the OpenIB gen1 stack. It "should" work with the Mellanox HPC Gold stack since it uses the OpenIB SDP and OpenSM code. The main performance issue there is getting AIO up and running so we can do non-blocking sends. But this quickly leads to a network layer rewrite so all layers can safely handle non-blocking sends and possibly non-blocking receives. This code has also not been touched since the last round of network changes, as can be seen from the compile issues, so other things may have changed that might cause issues. The VAPI code will have to be re-written as the VAPI interface in changing in the OpenIB gen2 stack. When this happens, a decision will have to be made if we rewrite the code to use the new VAPI interface, or we move to one of the DAPLs, or just settle on an MPI-2 layer for Chromium. SDP has some interesting IP/legal issues and might not be supported by all IB vendors in the future. I have exams for the next 2 weeks, but if all IB Chromium users can move to a standard stack, like the Mellanox stack, than we can try to work together to sort out the remaining issues towards the end of the month. -Mike |
From: Robert E. <pa...@tu...> - 2004-10-27 16:51:39
|
Hi, Mike - > I see you've updated the IB stuff, at least the makefiles, to use the > TopSpin stack. Yup, only the Makefiles (and one bad header declaration). I intended the change to be completely transparent to those who don't build IB (which I think must be nearly all, as the bad header declaration would have stopped any main trunk compilation of the IB support), negligible to all builders who don't have the TopSpin stack, and essential to those that do. > This is a really bad idea. You'll want to run the > OpenIB gen1 stack or better yet the Mellanox HPC Gold stack which is > public and "easy" to use. I'll defer to your IB expertise, as I'm not nearly as familiar with all the issues regarding competing stacks. In this particular instance, I was constrained to this particular stack; so other issues didn't enter the decision. On a related note, I was somewhat uncomfortable checking in Makefile changes, even as minor as this, to the public source, even though there are a few other examples of private or semi-private changes that snuck in here or here, that don't affect other folks... What's the right way to do this? Put them in as I did, allowing only extensions of the INCLUDE_DIRS and LDFLAGS variables so that users without the subdirectories won't be affected? Define a new variable to protect it from anyone who doesn't explicitly set the chosen variable? Don't do it at all (and maybe clean up the examples that are already there)? It may be nice to define some directory outside of the Chromium tree where custom files can be put (for commonly customized things like cr/options.mk, and maybe even custom SPU directories) to avoid both losing track of necessary local changes during a clean check-out, and to avoid accidentally commiting a local change to the repository... but I'm not sure the added utility would be worth the complexity required. Thanks for your insights, Bob Ellison Tungsten Graphics, Inc. |
From: Mike H. <mho...@gr...> - 2004-10-27 18:03:27
|
> > On a related note, I was somewhat uncomfortable checking in Makefile > changes, even as minor as this, to the public source, even though > there are a few other examples of private or semi-private changes that > snuck in here or here, that don't affect other folks... This probably doesn't matter a lot right now as there are only a few Chromium IB users and the IB stacks are still more painful to deal with in terms of userspace code than they should be, that a few added steps isn't much to deal with. My main concern is that it's going to be hard to deal with bug reports and layer issues unless we are all on the same stack. > > What's the right way to do this? Put them in as I did, allowing only > extensions of the INCLUDE_DIRS and LDFLAGS variables so that users > without the subdirectories won't be affected? Define a new variable > to protect it from anyone who doesn't explicitly set the chosen > variable? Don't do it at all (and maybe clean up the examples that > are already there)? This is why you have to enable IB support to get it compiled in, much like the other network layers. This is probably the best route, but we might want to move the definitions of INCLUDE_DIRS and LDFLAGS for IB support to options.mk as IB_INCLUDE_DIRS and IB_LDFLAGS so that a user knows if they want IB support that they need to modify the IB_SUPPORT flag as well as the paths. > > > It may be nice to define some directory outside of the Chromium tree > where custom files can be put (for commonly customized things like > cr/options.mk, and maybe even custom SPU directories) to avoid both > losing track of necessary local changes during a clean check-out, and > to avoid accidentally commiting a local change to the repository... > but I'm not sure the added utility would be worth the complexity > required. This is always tricky. I ran into this while doing Raptor. To build Raptor, it has to be in the Chromium tree (cr/progs/raptor). I just kept a separate CVS repository for this in my tree and 'cvs update' would do the right thing. I'm not sure what the best thing is on modifying central parts of Chromium for private work. I would suggest branching the tree, but of course then you have sync issues against the truck to contend with... In the end, I'm not sure there is a good answer. Having a known custom directory that overrides defaults, like options.mk, might not be a bad idea. Custom SPUs are probably better done with CVS within CVS like Raptor was done. Just my 2 cents. I struggle with this regularly myself. -Mike |