From d42488b98f91a151d8595e00bd3331f941cdf702 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 26 Jun 2017 06:44:57 -0600 Subject: [PATCH] Parallelize the action of the update_all_*_cell_dof_indices_caches() functions. --- source/dofs/dof_handler_policy.cc | 52 +++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/source/dofs/dof_handler_policy.cc b/source/dofs/dof_handler_policy.cc index 0a6a0957f6..3159e3ab5b 100644 --- a/source/dofs/dof_handler_policy.cc +++ b/source/dofs/dof_handler_policy.cc @@ -17,6 +17,7 @@ //TODO [TH]: renumber DoFs for multigrid is not done yet #include +#include #include #include #include @@ -68,11 +69,31 @@ namespace internal update_all_active_cell_dof_indices_caches (const DoFHandlerType &dof_handler) { typename DoFHandlerType::active_cell_iterator - cell = dof_handler.begin_active(), - endc = dof_handler.end(); - for (; cell != endc; ++cell) + beginc = dof_handler.begin_active(), + endc = dof_handler.end(); + + auto worker + = [] (const typename DoFHandlerType::active_cell_iterator &cell, + void *, + void *) + { if (!cell->is_artificial()) cell->update_cell_dof_indices_cache (); + }; + + // parallelize filling all of the cell caches. by using + // WorkStream, we make sure that we only run through the + // range of iterators once, whereas a parallel_for loop + // for example has to split the range multiple times, + // which is expensive because cell iterators are not + // random access iterators with a cheap operator- + WorkStream::run (beginc, endc, + worker, + /* copier */ std::function(), + /* scratch_data */ nullptr, + /* copy_data */ nullptr, + 2*MultithreadInfo::n_threads(), + /* chunk_size = */ 32); } @@ -85,11 +106,30 @@ namespace internal update_all_level_cell_dof_indices_caches (const DoFHandlerType &dof_handler) { typename DoFHandlerType::level_cell_iterator - cell = dof_handler.begin(), - endc = dof_handler.end(); + beginc = dof_handler.begin(), + endc = dof_handler.end(); - for (; cell != endc; ++cell) + auto worker + = [] (const typename DoFHandlerType::level_cell_iterator &cell, + void *, + void *) + { cell->update_cell_dof_indices_cache (); + }; + + // parallelize filling all of the cell caches. by using + // WorkStream, we make sure that we only run through the + // range of iterators once, whereas a parallel_for loop + // for example has to split the range multiple times, + // which is expensive because cell iterators are not + // random access iterators with a cheap operator- + WorkStream::run (beginc, endc, + worker, + /* copier */ std::function(), + /* scratch_data */ nullptr, + /* copy_data */ nullptr, + 2*MultithreadInfo::n_threads(), + /* chunk_size = */ 32); } } -- 2.39.5