From: Wolfgang Bangerth Date: Sun, 9 Aug 2015 23:07:27 +0000 (-0500) Subject: Parallelize FESystem::get_*_data(). X-Git-Tag: v8.4.0-rc2~632^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F1318%2Fhead;p=dealii.git Parallelize FESystem::get_*_data(). These functions call the respective functions in the base class. This may as well be done in parallel. --- diff --git a/source/fe/fe_system.cc b/source/fe/fe_system.cc index cb0883360d..38c7cf98a0 100644 --- a/source/fe/fe_system.cc +++ b/source/fe/fe_system.cc @@ -808,14 +808,25 @@ FESystem::get_data (const UpdateFlags flags_, data->update_each = update_each (flags); flags = data->update_once | data->update_each; - // get data objects from each of - // the base elements and store them + // get data objects from each of the base elements and store + // them. do the creation of these objects in parallel as their + // creation may be expensive (because we precompute a bunch of + // things) + std::vector::InternalDataBase *> > + get_data_tasks (this->n_base_elements()); + for (unsigned int base_no=0; base_non_base_elements(); ++base_no) + get_data_tasks[base_no] = Threads::new_task (&FiniteElement::get_data, + base_element(base_no), + flags, + mapping, + quadrature); + + // then wait for each of these calls to finish in turn and initialize + // these objects for (unsigned int base_no=0; base_non_base_elements(); ++base_no) { - // create internal objects for base elements and initialize their - // respective output objects typename FiniteElement::InternalDataBase *base_fe_data = - base_element(base_no).get_data(flags, mapping, quadrature); + get_data_tasks[base_no].return_value(); internal::FEValues::FiniteElementRelatedData &base_fe_output_object = data->get_fe_output_object(base_no); @@ -847,12 +858,25 @@ FESystem::get_face_data ( data->update_each = update_each (flags); flags = data->update_once | data->update_each; + // get data objects from each of the base elements and store + // them. do the creation of these objects in parallel as their + // creation may be expensive (because we precompute a bunch of + // things) + std::vector::InternalDataBase *> > + get_data_tasks (this->n_base_elements()); + for (unsigned int base_no=0; base_non_base_elements(); ++base_no) + get_data_tasks[base_no] = Threads::new_task (&FiniteElement::get_face_data, + base_element(base_no), + flags, + mapping, + quadrature); + + // then wait for each of these calls to finish in turn and initialize + // these objects for (unsigned int base_no=0; base_non_base_elements(); ++base_no) { - // create internal objects for base elements and initialize their - // respective output objects typename FiniteElement::InternalDataBase *base_fe_data = - base_element(base_no).get_face_data(flags, mapping, quadrature); + get_data_tasks[base_no].return_value(); internal::FEValues::FiniteElementRelatedData &base_fe_output_object = data->get_fe_output_object(base_no); @@ -886,12 +910,25 @@ FESystem::get_subface_data ( data->update_each = update_each (flags); flags = data->update_once | data->update_each; + // get data objects from each of the base elements and store + // them. do the creation of these objects in parallel as their + // creation may be expensive (because we precompute a bunch of + // things) + std::vector::InternalDataBase *> > + get_data_tasks (this->n_base_elements()); + for (unsigned int base_no=0; base_non_base_elements(); ++base_no) + get_data_tasks[base_no] = Threads::new_task (&FiniteElement::get_subface_data, + base_element(base_no), + flags, + mapping, + quadrature); + + // then wait for each of these calls to finish in turn and initialize + // these objects for (unsigned int base_no=0; base_non_base_elements(); ++base_no) { - // create internal objects for base elements and initialize their - // respective output objects typename FiniteElement::InternalDataBase *base_fe_data = - base_element(base_no).get_subface_data(flags, mapping, quadrature); + get_data_tasks[base_no].return_value(); internal::FEValues::FiniteElementRelatedData &base_fe_output_object = data->get_fe_output_object(base_no);