From: bangerth Date: Tue, 24 Dec 2013 15:06:56 +0000 (+0000) Subject: First step towards using parallel_for whenever the copier function is X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0aa003543ed1321d3f559e345647beeb454cb475;p=dealii-svn.git First step towards using parallel_for whenever the copier function is empty: defer from implementation 2 to implementation 3. git-svn-id: https://svn.dealii.org/trunk@32113 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/include/deal.II/base/work_stream.h b/deal.II/include/deal.II/base/work_stream.h index 63007aba91..6bb40efccb 100644 --- a/deal.II/include/deal.II/base/work_stream.h +++ b/deal.II/include/deal.II/base/work_stream.h @@ -1171,6 +1171,21 @@ namespace WorkStream #endif // DEAL_II_WITH_THREADS + // implementation 3 forward declaration + template + void + run (const std::vector > &colored_iterators, + Worker worker, + Copier copier, + const ScratchData &sample_scratch_data, + const CopyData &sample_copy_data, + const unsigned int queue_length, + const unsigned int chunk_size); + /** * This is one of two main functions of the WorkStream concept, doing work as @@ -1260,17 +1275,17 @@ namespace WorkStream #ifdef DEAL_II_WITH_THREADS else // have TBB and use more than one thread { - // create the three stages of the pipeline - internal::Implementation2::IteratorRangeToItemStream - iterator_range_to_item_stream (begin, end, - queue_length, - chunk_size, - sample_scratch_data, - sample_copy_data); - // Check that the copier exist if (static_cast& >(copier)) { + // create the three stages of the pipeline + internal::Implementation2::IteratorRangeToItemStream + iterator_range_to_item_stream (begin, end, + queue_length, + chunk_size, + sample_scratch_data, + sample_copy_data); + internal::Implementation2::Worker worker_filter (worker); internal::Implementation2::Copier copier_filter (copier); @@ -1287,17 +1302,30 @@ namespace WorkStream } else { - internal::Implementation2::Worker worker_filter (worker,false); - - // now create a pipeline from these stages - tbb::pipeline assembly_line; - assembly_line.add_filter (iterator_range_to_item_stream); - assembly_line.add_filter (worker_filter); - - // and run it - assembly_line.run (queue_length); - - assembly_line.clear (); + // there is no copier function. in this case, we have an + // embarrassingly parallel problem where we can + // essentially apply parallel_for. because parallel_for + // requires subdividing the range for which operator- is + // necessary between iterators, it is often inefficient to + // apply it directory to cell ranges and similar iterator + // types for which operator- is expensive or, in fact, + // nonexistent. rather, in that case, we simply copy the + // iterators into a large array and use operator- on + // iterators to this array of iterators. + // + // instead of duplicating code, this is essentially the + // same situation we have in Implementation3 below, so we + // just defer to that place + std::vector > all_iterators (1); + for (Iterator p=begin; p!=end; ++p) + all_iterators[0].push_back (p); + + run (all_iterators, + worker, copier, + sample_scratch_data, + sample_copy_data, + queue_length, + chunk_size); } } #endif