The idea definitely sounds promising, but I will caution against
unnecessary complication in the name of memory optimization.
In Sierra no Mesh object (node, element, face etc..) knows its own
type (MeshObj is essentially a typeless container)... therefore the
code itself must keep track of which type is which and sort it out
when necessary. At first this sounds like a great idea (MeshObj are
really light... and really general) until you actually start
implementing in code... and you end up dynamic casting all over the
place to figure out what is what. It makes things that should be
relatively simple _much_ more difficult (like seeing if a point lies
within an element... I'll give you an example of this on Monday).
This is mostly a subsystem change, but you have to consider that if
you want to bring outside FE developers in to help.... the more of
these things you do the harder it is for someone to get in there and
change things. Keeping subsystems logically similar to how someone
new to the code would think about it is advantageous in the long run.
(but of course the whole dofobject thing is fairly complicated now
anyway, so a little added complication might not hurt ;-)
Anyway, what you are proposing isn't going that far... I'm just trying
to illustrate some of the pitfalls of "over optimization".
Essentially, if you were to take memory optimization to the max....
you would end up with Sierra... and I think _none_ of us wants that!
For me, the most worthwhile optimization endeavor is parallel mesh.
All day long I talk about how great libMesh is to all my coworkers at
Sandia... and when I show them code snippets they go "wow" because of
how simple it is to get seemingly complicated things done (things that
would take a month to do in Sierra can be done in 10 minutes in
libMesh). But then the discussion _always_ comes back to: "But does
it do parallel mesh?"... and then I have to digress....
On 2/24/07, Roy Stogner <roystgnr@...> wrote:
> I'm never going to find time to implement this myself, but I thought
> I'd throw it out there in case anyone else is interested:
> With reference counting off, DofObjects in libMesh currently have:
> DofObject *old_dof_object
> int _id
> short int _processor_id
> char _n_systems
> (probably 1 byte alignment padding here)
> unsigned char *_n_vars
> unsigned char **_n_comp
> unsigned char **_dof_ids
> That's 24 bytes on a 32 bit system, 40 bytes on an LP64 bit system.
> But, the pointers are all pointing to things allocated on the heap...
> does anyone know how much memory management overhead we get with g++
> and the default new()?
> Even with 0 overhead, we still end up with at least an additional byte
> and two pointers per system, plus a byte and an int per variable...
> and then the old_dof_object doubles that. For Vikram's code, as an
> example, with 3 systems and up to 5 variables on each node, that's
> something like 152 bytes on a 32 bit system or 232 bytes on an LP64
> So here's my thought:
> What if we have this for each DofObject:
> int _id
> short int _processor_id
> char _dof_object_type
> char _old_dof_object_type
> int _per_type_id
> int _old_per_type_id
> And this for each DofMap:
> std::vector<int> dof_renumbering(n_dofs)
> That's 16 bytes per DofObject, plus 4 bytes per variable (totaling up
> to 36 bytes per node in Vikram's code), with no allocator overhead.
> The _dof_object_type tells the DofMap what kind of object it is: Elem,
> vertex, hanging vertex/edge, hanging vertex/face, edge, etc. Likewise
> for the _old_dof_object_type. The _per_type_id numbers each type of
> DofObject from 0 to (e.g.) n_vertices; likewise for _old_per_type_id.
> The "raw" dof numbering then goes in order by object type: all the
> vertices first, all the edges next, all the faces third, etc. With
> isotropic refinement, there should only be a dozen or two types of
> Because n_comp is the same for DofObjects of the same
> _dof_object_type, to get the dof numbering for a variable on a DoF
> object you just add: for the v variable on an edge in a u/v/p system,
> for example, the raw global DoF index is:
> raw_global_index = n_u_dofs + n_v_vertices*n_v_dofs_per_vertex +
> _per_type_id*n_v_dofs_per_edge + edge_local_index
> And the global DoF index is dof_renumbering[raw_global_index]
> (which is necessary, most importantly to keep DoFs on each processor
> This is probably way too much work to save what may add up to only a
> hundred megs of RAM... but it seems in my experience that Mesh
> objects are taking more memory than they should, and the first suspect
> IMHO is the DofObject class.
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys-and earn cash
> Libmesh-devel mailing list