From 3148198b0cf803f555793cabaac50c9a69c64bbc Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 26 Sep 2016 16:49:55 -0500 Subject: [PATCH] Parallelize the operation of compute_number_cache(). For these functions, the 3d version calls the 2d version which itself calls the 1d version. These operations can all run concurrently. All three include two loops each over all cells/quads/lines, so there should be plenty to do to amortize parallel execution. The only tricky part is that the quad and hex functions accessed a variable that was first set by the 1d function (number_cache.n_lines). This may now no longer be available in time for the 2d/3d functions, and so they need to compute this information themselves. This is cheap, fortunately. --- source/grid/tria.cc | 86 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/source/grid/tria.cc b/source/grid/tria.cc index e5e5f94374..4afb503ada 100644 --- a/source/grid/tria.cc +++ b/source/grid/tria.cc @@ -1409,37 +1409,57 @@ namespace internal const unsigned int level_objects, internal::Triangulation::NumberCache<2> &number_cache) { - // update lines and n_levels - compute_number_cache (triangulation, - level_objects, - static_cast&> - (number_cache)); + // update lines and n_levels in number_cache. since we don't + // access any of these numbers, we can do this in the + // background + Threads::Task update_lines + = Threads::new_task ((void (*)(const Triangulation &, + const unsigned int, + internal::Triangulation::NumberCache<1> &)) + (&compute_number_cache), + triangulation, + level_objects, + static_cast&> + (number_cache)); typedef typename Triangulation::quad_iterator quad_iterator; typedef typename Triangulation::active_quad_iterator active_quad_iterator; + // count the number of levels; the function we called above + // for lines also does this and puts it into + // number_cache.n_levels, but this datum may not yet be + // available as we call the function on a separate task + unsigned int n_levels = 0; + if (level_objects > 0) + // find the last level on which there are used cells + for (unsigned int level=0; level &number_cache) { - // update quads, lines and n_levels - compute_number_cache (triangulation, - level_objects, - static_cast&> - (number_cache)); + // update quads, lines and n_levels in number_cache. since we + // don't access any of these numbers, we can do this in the + // background + Threads::Task update_quads_and_lines + = Threads::new_task ((void (*)(const Triangulation &, + const unsigned int, + internal::Triangulation::NumberCache<2> &)) + (&compute_number_cache), + triangulation, + level_objects, + static_cast&> + (number_cache)); typedef typename Triangulation::hex_iterator hex_iterator; typedef typename Triangulation::active_hex_iterator active_hex_iterator; + // count the number of levels; the function we called above + // for quads (recursively, via the lines function) also does + // this and puts it into number_cache.n_levels, but this datum + // may not yet be available as we call the function on a + // separate task + unsigned int n_levels = 0; + if (level_objects > 0) + // find the last level on which there are used cells + for (unsigned int level=0; level