Skip to content

Draft: Use less allocations on UGGrid intersection geometries

Currently, UGGrid intersection geometries do many allocations for very small objects. In simple simulations I get millions (!) of allocation calls due to this, a few orders of magnitude higher than any other allocation in a simulation. This happens because

  • The geometry object is stored as a shared pointer. While this is handy when having several geometries referring to the same intersection, this is barely of any use as we mostly expect people to have one geometry and get it from the entity. An optional type is more appropriate here.
  • The coordinates are a std::vector of field vectors that need to be created for every geometry. While is nice having a geometry that has ownership of the coordinates because it could technically outlive the grid, but in any case, this cannot be reliably exploited as UGGridEntity::UGridGeometry does not own its coordinates either. This can be solved by generating the coordinates on-demand with std::function.
  • Every new intersection stores a std::vector of faces. While this is needed for the non-conforming case, it penalizes the common case where there is one or no faces neighboring the intersection. This can be solved by properly using a union type, i.e. std::variant

The current MR mitigates the first issue by using std::optional, the second one by generating the coordinates on the fly with std::function (WIP), and the third one by using std::variant. All of them optimized to not allocate anything on the hot-path but still be flexible to allocate if needed.

Edited by Santiago Ospina De Los Ríos

Merge request reports

Loading