>> Of course, restructuring the whole libMesh library such as to use a
>> ghosted concept that matches PETSc's concept is utopic, so we can't
>> remove all inefficiencies.
>
> The only issue there is local vs. global index lookups: we currently
> only expose global dof indices to the user, and so had the hard (and
> slightly inefficient, especially for non-owned indices) task of going
> global->local when accessing a ghosted vector.
>
> While we can't change global->local dof indices in the library without
> breaking user codes, we can change the underlying representation and
> add APIs to expose local dof numbers as well, at which point much of
> the library code could be changed to access vectors more efficiently
> via local dof number instead. That would be much more work than I (or
> anyone else, probably) will have time to do any time soon, but there's
> nothing in the design that prohibits it.
I don't see why only exposing the global indices is a problem, the mapping
*should* be pretty lightweight:
unsigned int PetscVector<T>::map_global_to_local_index (const unsigned int
i) const
{
00945 libmesh_assert (this->initialized());
00946
00947 const unsigned int first = this->first_local_index();
00948 const unsigned int last = this->last_local_index();
00949
00950 if((i>=first) && (i<last))
00951 {
00952 return i-first;
00953 }
00954
00955 GlobalToLocalMap::const_iterator it = _global_to_local_map.find(i);
00956 libmesh_assert (it!=_global_to_local_map.end());
00957 return it->second+last-first;
00958 }
Two obvious optimizations seem possible, though. the
this->first_local_index() and this->last_local_index() both perform the same
underlying PETSc call to get *both* [local_min, local_max) and only return
the QOI.
This could be streamlined with
std::pair<unsigned int, unsigned int> PetscVector::local_index_range() or
something like that, eliminating a redundant call. Also, if this is in fact
a performance issue, we could cache these values at the expense of
additional bookkeeping.
Then there is the fact that the GlobalToLoalMap is derived from a
std::map...
std::map is very convenient for building up the list, but is not so
efficient in terms of access or memory requirements.
What I would suggest in this case and can take a hack at instead is that
GlobalToLocalMap be derived from std::vector. It seems natural since the
API provides a vector in the first place. we then just sort this vector and
do the lookups with binary searches, which should smoke the map in terms of
memory and access time performance.
If you would like I could give this a shot, and in doing so I'd extend
GlobalToLocalMap a bit to further encapsulate this. in the future we could
then switch implementations transparently.
Thoughts? The former change should be easy, not sure the payoff - but the
latter change will likely help quite a bit.
-Ben
------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
Libmesh-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libmesh-devel