multiway_merge.h: Reformat to 80 columns; adjust some inline specifiers; other minor style fixes.
2008-01-09 Paolo Carlini <pcarlini@suse.de> * include/parallel/multiway_merge.h: Reformat to 80 columns; adjust some inline specifiers; other minor style fixes. * include/parallel/losertree.h: Likewise. * include/parallel/list_partition.h: Likewise. * include/parallel/multiseq_selection.h: Likewise. * include/parallel/workstealing.h: Likewise. * include/parallel/base.h: Likewise. * include/parallel/par_loop.h: Likewise. * include/parallel/numeric: Likewise. * include/parallel/quicksort.h: Likewise. * include/parallel/algorithmfwd.h: Likewise. * include/parallel/for_each_selectors.h: Likewise. * include/parallel/omp_loop_static.h: Likewise. * include/parallel/random_shuffle.h: Likewise. * include/parallel/balanced_quicksort.h: Likewise. * include/parallel/set_operations.h: Likewise. * include/parallel/tree.h: Likewise. * include/parallel/merge.h: Likewise. * include/parallel/unique_copy.h: Likewise. * include/parallel/settings.h: Likewise. * include/parallel/multiway_mergesort.h: Likewise. * include/parallel/numericfwd.h: Likewise. * include/parallel/search.h: Likewise. * include/parallel/partition.h: Likewise. * include/parallel/compatibility.h: Likewise. * include/parallel/partial_sum.h: Likewise. * include/parallel/find.h: Likewise. * include/parallel/algo.h: Likewise. * include/parallel/queue.h: Likewise. * include/parallel/omp_loop.h: Likewise. * include/parallel/sort.h: Likewise. * include/parallel/random_number.h: Likewise. From-SVN: r131440
This commit is contained in:
parent
299f57348c
commit
5817ff8e5f
32 changed files with 3871 additions and 3356 deletions
|
@ -1,3 +1,38 @@
|
|||
2008-01-09 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
* include/parallel/multiway_merge.h: Reformat to 80 columns;
|
||||
adjust some inline specifiers; other minor style fixes.
|
||||
* include/parallel/losertree.h: Likewise.
|
||||
* include/parallel/list_partition.h: Likewise.
|
||||
* include/parallel/multiseq_selection.h: Likewise.
|
||||
* include/parallel/workstealing.h: Likewise.
|
||||
* include/parallel/base.h: Likewise.
|
||||
* include/parallel/par_loop.h: Likewise.
|
||||
* include/parallel/numeric: Likewise.
|
||||
* include/parallel/quicksort.h: Likewise.
|
||||
* include/parallel/algorithmfwd.h: Likewise.
|
||||
* include/parallel/for_each_selectors.h: Likewise.
|
||||
* include/parallel/omp_loop_static.h: Likewise.
|
||||
* include/parallel/random_shuffle.h: Likewise.
|
||||
* include/parallel/balanced_quicksort.h: Likewise.
|
||||
* include/parallel/set_operations.h: Likewise.
|
||||
* include/parallel/tree.h: Likewise.
|
||||
* include/parallel/merge.h: Likewise.
|
||||
* include/parallel/unique_copy.h: Likewise.
|
||||
* include/parallel/settings.h: Likewise.
|
||||
* include/parallel/multiway_mergesort.h: Likewise.
|
||||
* include/parallel/numericfwd.h: Likewise.
|
||||
* include/parallel/search.h: Likewise.
|
||||
* include/parallel/partition.h: Likewise.
|
||||
* include/parallel/compatibility.h: Likewise.
|
||||
* include/parallel/partial_sum.h: Likewise.
|
||||
* include/parallel/find.h: Likewise.
|
||||
* include/parallel/algo.h: Likewise.
|
||||
* include/parallel/queue.h: Likewise.
|
||||
* include/parallel/omp_loop.h: Likewise.
|
||||
* include/parallel/sort.h: Likewise.
|
||||
* include/parallel/random_number.h: Likewise.
|
||||
|
||||
2008-01-09 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
* docs/html/17_intro/api.html: Fix markup for rope.h.
|
||||
|
|
|
@ -90,12 +90,10 @@ namespace __parallel
|
|||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
for_each_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::for_each_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
bool dummy;
|
||||
__gnu_parallel::for_each_selector<RandomAccessIterator>
|
||||
|
@ -333,10 +331,9 @@ namespace __parallel
|
|||
RandomAccessOutputIterator out, Predicate pred,
|
||||
random_access_iterator_tag, random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(last - begin)
|
||||
> __gnu_parallel::Settings::
|
||||
unique_copy_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(last - begin)
|
||||
> __gnu_parallel::Settings::unique_copy_minimal_n))
|
||||
return __gnu_parallel::parallel_unique_copy(begin, last, out, pred);
|
||||
else
|
||||
return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred);
|
||||
|
@ -414,14 +411,11 @@ namespace __parallel
|
|||
random_access_iterator_tag, random_access_iterator_tag,
|
||||
random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::
|
||||
set_union_minimal_n
|
||||
|| static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::
|
||||
set_union_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::set_union_minimal_n
|
||||
|| static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::set_union_minimal_n))
|
||||
return __gnu_parallel::parallel_set_union(begin1, end1,
|
||||
begin2, end2, result, pred);
|
||||
else
|
||||
|
@ -523,14 +517,11 @@ namespace __parallel
|
|||
random_access_iterator_tag,
|
||||
random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::
|
||||
set_union_minimal_n
|
||||
|| static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::
|
||||
set_union_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::set_union_minimal_n
|
||||
|| static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::set_union_minimal_n))
|
||||
return __gnu_parallel::parallel_set_intersection(begin1, end1, begin2,
|
||||
end2, result, pred);
|
||||
else
|
||||
|
@ -639,14 +630,11 @@ namespace __parallel
|
|||
random_access_iterator_tag,
|
||||
random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::
|
||||
set_symmetric_difference_minimal_n
|
||||
|| static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::
|
||||
set_symmetric_difference_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::set_symmetric_difference_minimal_n
|
||||
|| static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::set_symmetric_difference_minimal_n))
|
||||
return __gnu_parallel::parallel_set_symmetric_difference(begin1, end1,
|
||||
begin2, end2,
|
||||
result, pred);
|
||||
|
@ -751,14 +739,11 @@ namespace __parallel
|
|||
random_access_iterator_tag,
|
||||
random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::
|
||||
set_difference_minimal_n
|
||||
|| static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::
|
||||
set_difference_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::set_difference_minimal_n
|
||||
|| static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::set_difference_minimal_n))
|
||||
return __gnu_parallel::parallel_set_difference(begin1, end1,
|
||||
begin2, end2,
|
||||
result, pred);
|
||||
|
@ -926,12 +911,10 @@ namespace __parallel
|
|||
typedef typename traits_type::difference_type difference_type;
|
||||
typedef __gnu_parallel::sequence_index_t sequence_index_t;
|
||||
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<sequence_index_t>
|
||||
(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
count_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::count_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
__gnu_parallel::count_selector<RandomAccessIterator, difference_type>
|
||||
functionality;
|
||||
|
@ -996,12 +979,10 @@ namespace __parallel
|
|||
typedef typename traits_type::difference_type difference_type;
|
||||
typedef __gnu_parallel::sequence_index_t sequence_index_t;
|
||||
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<sequence_index_t>
|
||||
(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
count_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::count_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
difference_type res = 0;
|
||||
__gnu_parallel::
|
||||
|
@ -1239,12 +1220,10 @@ namespace __parallel
|
|||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
transform_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::transform_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
bool dummy = true;
|
||||
typedef __gnu_parallel::iterator_pair<RandomAccessIterator1,
|
||||
|
@ -1330,11 +1309,9 @@ namespace __parallel
|
|||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION((end1 - begin1)
|
||||
>= __gnu_parallel::Settings::
|
||||
transform_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
(end1 - begin1) >= __gnu_parallel::Settings::transform_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
bool dummy = true;
|
||||
typedef __gnu_parallel::iterator_triple<RandomAccessIterator1,
|
||||
|
@ -1489,12 +1466,10 @@ namespace __parallel
|
|||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
replace_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::replace_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
bool dummy;
|
||||
__gnu_parallel::
|
||||
|
@ -1556,12 +1531,10 @@ namespace __parallel
|
|||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
generate_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::generate_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
bool dummy;
|
||||
__gnu_parallel::generate_selector<RandomAccessIterator>
|
||||
|
@ -1686,10 +1659,9 @@ namespace __parallel
|
|||
{
|
||||
if (begin == end)
|
||||
return;
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
random_shuffle_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::random_shuffle_minimal_n))
|
||||
__gnu_parallel::parallel_random_shuffle(begin, end, rand);
|
||||
else
|
||||
__gnu_parallel::sequential_random_shuffle(begin, end, rand);
|
||||
|
@ -1715,10 +1687,9 @@ namespace __parallel
|
|||
partition_switch(RandomAccessIterator begin, RandomAccessIterator end,
|
||||
Predicate pred, random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
partition_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::partition_minimal_n))
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::
|
||||
difference_type difference_type;
|
||||
|
@ -1775,10 +1746,9 @@ namespace __parallel
|
|||
|
||||
if (begin != end)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
sort_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::sort_minimal_n))
|
||||
__gnu_parallel::parallel_sort(begin, end, comp, false);
|
||||
else
|
||||
sort(begin, end, comp, __gnu_parallel::sequential_tag());
|
||||
|
@ -1816,10 +1786,9 @@ namespace __parallel
|
|||
{
|
||||
if (begin != end)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
sort_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::sort_minimal_n))
|
||||
__gnu_parallel::parallel_sort(begin, end, comp, true);
|
||||
else
|
||||
stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
|
||||
|
@ -1866,14 +1835,11 @@ namespace __parallel
|
|||
random_access_iterator_tag, random_access_iterator_tag,
|
||||
random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION((static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::
|
||||
merge_minimal_n
|
||||
|| static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::
|
||||
merge_minimal_n)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
(static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
|
||||
>= __gnu_parallel::Settings::merge_minimal_n
|
||||
|| static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
|
||||
>= __gnu_parallel::Settings::merge_minimal_n)))
|
||||
return __gnu_parallel::parallel_merge_advance(begin1, end1,
|
||||
begin2, end2,
|
||||
result, (end1 - begin1)
|
||||
|
@ -1945,10 +1911,9 @@ namespace __parallel
|
|||
nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
|
||||
RandomAccessIterator end, Comparator comp)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
nth_element_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::nth_element_minimal_n))
|
||||
__gnu_parallel::parallel_nth_element(begin, nth, end, comp);
|
||||
else
|
||||
nth_element(begin, nth, end, comp, __gnu_parallel::sequential_tag());
|
||||
|
@ -1986,10 +1951,9 @@ namespace __parallel
|
|||
partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
|
||||
RandomAccessIterator end, _Compare comp)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
partial_sort_minimal_n))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::partial_sort_minimal_n))
|
||||
__gnu_parallel::parallel_partial_sort(begin, middle, end, comp);
|
||||
else
|
||||
partial_sort(begin, middle, end, comp,
|
||||
|
@ -2036,12 +2000,10 @@ namespace __parallel
|
|||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
max_element_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::max_element_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
RandomAccessIterator res(begin);
|
||||
__gnu_parallel::identity_selector<RandomAccessIterator>
|
||||
|
@ -2129,12 +2091,10 @@ namespace __parallel
|
|||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
min_element_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::min_element_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
RandomAccessIterator res(begin);
|
||||
__gnu_parallel::identity_selector<RandomAccessIterator>
|
||||
|
|
|
@ -454,8 +454,8 @@ namespace __parallel
|
|||
_RAIter3
|
||||
transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation,
|
||||
random_access_iterator_tag, random_access_iterator_tag,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism parallelism_tag);
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename _OIter,
|
||||
typename _BiOperation, typename _Tag1,
|
||||
|
@ -525,7 +525,7 @@ namespace __parallel
|
|||
|
||||
template<typename _FIter>
|
||||
_FIter
|
||||
max_element(_FIter, _FIter, __gnu_parallel::parallelism parallelism_tag);
|
||||
max_element(_FIter, _FIter, __gnu_parallel::parallelism);
|
||||
|
||||
template<typename _FIter, typename _Compare>
|
||||
_FIter
|
||||
|
|
|
@ -112,8 +112,9 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
|
||||
RandomAccessIterator pivot_pos = median_of_three_iterators(
|
||||
begin, begin + (end - begin) / 2, end - 1, comp);
|
||||
RandomAccessIterator pivot_pos =
|
||||
median_of_three_iterators(begin, begin + (end - begin) / 2,
|
||||
end - 1, comp);
|
||||
|
||||
#if defined(_GLIBCXX_ASSERTIONS)
|
||||
// Must be in between somewhere.
|
||||
|
@ -146,9 +147,9 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
|
||||
#if _GLIBCXX_ASSERTIONS
|
||||
RandomAccessIterator r;
|
||||
for (r = begin; r != pivot_pos; r++)
|
||||
for (r = begin; r != pivot_pos; ++r)
|
||||
_GLIBCXX_PARALLEL_ASSERT(comp(*r, *pivot_pos));
|
||||
for (; r != end; r++)
|
||||
for (; r != end; ++r)
|
||||
_GLIBCXX_PARALLEL_ASSERT(!comp(*r, *pivot_pos));
|
||||
#endif
|
||||
|
||||
|
@ -308,12 +309,12 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
__gnu_parallel::unary_negate<__gnu_parallel::binder1st
|
||||
<Comparator, value_type, value_type, bool>, value_type>
|
||||
pred(__gnu_parallel::binder1st
|
||||
<Comparator, value_type, value_type, bool>(
|
||||
comp, *pivot_pos));
|
||||
<Comparator, value_type, value_type, bool>(comp,
|
||||
*pivot_pos));
|
||||
|
||||
// Find other end of pivot-equal range.
|
||||
split_pos2 = __gnu_sequential::partition(
|
||||
split_pos1 + 1, end, pred);
|
||||
split_pos2 = __gnu_sequential::partition(split_pos1 + 1,
|
||||
end, pred);
|
||||
}
|
||||
else
|
||||
// Only skip the pivot.
|
||||
|
@ -339,8 +340,8 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
{
|
||||
// Left side larger.
|
||||
if (begin != split_pos1)
|
||||
tl.leftover_parts.push_front(
|
||||
std::make_pair(begin, split_pos1));
|
||||
tl.leftover_parts.push_front(std::make_pair(begin,
|
||||
split_pos1));
|
||||
|
||||
current.first = split_pos2;
|
||||
//current.second = end; //already set anyway
|
||||
|
@ -394,8 +395,8 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
if (omp_get_wtime() >= (search_start + 1.0))
|
||||
{
|
||||
sleep(1);
|
||||
_GLIBCXX_PARALLEL_ASSERT(
|
||||
omp_get_wtime() < (search_start + 1.0));
|
||||
_GLIBCXX_PARALLEL_ASSERT(omp_get_wtime()
|
||||
< (search_start + 1.0));
|
||||
}
|
||||
#endif
|
||||
if (!successfully_stolen)
|
||||
|
@ -452,7 +453,7 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
// 2. The largest range has at most length n
|
||||
// 3. Each range is larger than half of the range remaining
|
||||
volatile difference_type elements_leftover = n;
|
||||
for (int i = 0; i < num_threads; i++)
|
||||
for (int i = 0; i < num_threads; ++i)
|
||||
{
|
||||
tls[i]->elements_leftover = &elements_leftover;
|
||||
tls[i]->num_threads = num_threads;
|
||||
|
@ -468,11 +469,11 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
#if _GLIBCXX_ASSERTIONS
|
||||
// All stack must be empty.
|
||||
Piece dummy;
|
||||
for (int i = 1; i < num_threads; i++)
|
||||
for (int i = 1; i < num_threads; ++i)
|
||||
_GLIBCXX_PARALLEL_ASSERT(!tls[i]->leftover_parts.pop_back(dummy));
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < num_threads; i++)
|
||||
for (int i = 0; i < num_threads; ++i)
|
||||
delete tls[i];
|
||||
delete[] tls;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -96,17 +96,13 @@ decode2(lcas_t x, int& a, int& b)
|
|||
template<typename T>
|
||||
const T&
|
||||
min(const T& a, const T& b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
};
|
||||
{ return (a < b) ? a : b; }
|
||||
|
||||
/** @brief Equivalent to std::max. */
|
||||
template<typename T>
|
||||
const T&
|
||||
max(const T& a, const T& b)
|
||||
{
|
||||
return (a > b) ? a : b;
|
||||
};
|
||||
{ return (a > b) ? a : b; }
|
||||
|
||||
/** @brief Constructs predicate for equality from strict weak
|
||||
* ordering predicate
|
||||
|
@ -402,7 +398,7 @@ template<typename _ValueTp>
|
|||
* @param comp Comparator.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename Comparator>
|
||||
RandomAccessIterator
|
||||
RandomAccessIterator
|
||||
median_of_three_iterators(RandomAccessIterator a, RandomAccessIterator b,
|
||||
RandomAccessIterator c, Comparator& comp)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -105,7 +105,8 @@ namespace __gnu_parallel
|
|||
#elif defined(__ECC) //IA-64 version
|
||||
return _InterlockedExchangeAdd((void*)ptr, addend);
|
||||
#elif defined(__ICL) || defined(_MSC_VER)
|
||||
return _InterlockedExchangeAdd(reinterpret_cast<volatile long*>(ptr), addend);
|
||||
return _InterlockedExchangeAdd(reinterpret_cast<volatile long*>(ptr),
|
||||
addend);
|
||||
#elif defined(__GNUC__)
|
||||
return __sync_fetch_and_add(ptr, addend);
|
||||
#elif defined(__SUNPRO_CC) && defined(__sparc)
|
||||
|
@ -114,7 +115,8 @@ namespace __gnu_parallel
|
|||
{
|
||||
before = *ptr;
|
||||
after = before + addend;
|
||||
} while (atomic_cas_32((volatile unsigned int*)ptr, before, after) != before);
|
||||
} while (atomic_cas_32((volatile unsigned int*)ptr, before,
|
||||
after) != before);
|
||||
return before;
|
||||
#else //fallback, slow
|
||||
#pragma message("slow fetch_and_add_32")
|
||||
|
@ -159,7 +161,8 @@ namespace __gnu_parallel
|
|||
{
|
||||
before = *ptr;
|
||||
after = before + addend;
|
||||
} while (atomic_cas_64((volatile unsigned long long*)ptr, before, after) != before);
|
||||
} while (atomic_cas_64((volatile unsigned long long*)ptr, before,
|
||||
after) != before);
|
||||
return before;
|
||||
#else //fallback, slow
|
||||
#if defined(__GNUC__) && defined(__i386)
|
||||
|
@ -238,15 +241,19 @@ namespace __gnu_parallel
|
|||
compare_and_swap_32(volatile int32* ptr, int32 comparand, int32 replacement)
|
||||
{
|
||||
#if defined(__ICC) //x86 version
|
||||
return _InterlockedCompareExchange((void*)ptr, replacement, comparand) == comparand;
|
||||
return _InterlockedCompareExchange((void*)ptr, replacement,
|
||||
comparand) == comparand;
|
||||
#elif defined(__ECC) //IA-64 version
|
||||
return _InterlockedCompareExchange((void*)ptr, replacement, comparand) == comparand;
|
||||
return _InterlockedCompareExchange((void*)ptr, replacement,
|
||||
comparand) == comparand;
|
||||
#elif defined(__ICL) || defined(_MSC_VER)
|
||||
return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr), replacement, comparand) == comparand;
|
||||
return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr),
|
||||
replacement, comparand) == comparand;
|
||||
#elif defined(__GNUC__)
|
||||
return __sync_bool_compare_and_swap(ptr, comparand, replacement);
|
||||
#elif defined(__SUNPRO_CC) && defined(__sparc)
|
||||
return atomic_cas_32((volatile unsigned int*)ptr, comparand, replacement) == comparand;
|
||||
return atomic_cas_32((volatile unsigned int*)ptr, comparand,
|
||||
replacement) == comparand;
|
||||
#else
|
||||
#pragma message("slow compare_and_swap_32")
|
||||
bool res = false;
|
||||
|
@ -276,13 +283,15 @@ namespace __gnu_parallel
|
|||
#if defined(__ICC) && defined(__x86_64) //x86 version
|
||||
return cas64<int>(ptr, comparand, replacement) == comparand;
|
||||
#elif defined(__ECC) //IA-64 version
|
||||
return _InterlockedCompareExchange64((void*)ptr, replacement, comparand) == comparand;
|
||||
return _InterlockedCompareExchange64((void*)ptr, replacement,
|
||||
comparand) == comparand;
|
||||
#elif defined(__ICL) || defined(_MSC_VER)
|
||||
#ifndef _WIN64
|
||||
_GLIBCXX_PARALLEL_ASSERT(false); //not available in this case
|
||||
return 0;
|
||||
#else
|
||||
return _InterlockedCompareExchange64(ptr, replacement, comparand) == comparand;
|
||||
return _InterlockedCompareExchange64(ptr, replacement,
|
||||
comparand) == comparand;
|
||||
#endif
|
||||
|
||||
#elif defined(__GNUC__) && defined(__x86_64)
|
||||
|
@ -291,7 +300,8 @@ namespace __gnu_parallel
|
|||
(defined(__i686) || defined(__pentium4) || defined(__athlon))
|
||||
return __sync_bool_compare_and_swap(ptr, comparand, replacement);
|
||||
#elif defined(__SUNPRO_CC) && defined(__sparc)
|
||||
return atomic_cas_64((volatile unsigned long long*)ptr, comparand, replacement) == comparand;
|
||||
return atomic_cas_64((volatile unsigned long long*)ptr,
|
||||
comparand, replacement) == comparand;
|
||||
#else
|
||||
#if defined(__GNUC__) && defined(__i386)
|
||||
// XXX -march=native
|
||||
|
@ -323,9 +333,11 @@ namespace __gnu_parallel
|
|||
compare_and_swap(volatile T* ptr, T comparand, T replacement)
|
||||
{
|
||||
if (sizeof(T) == sizeof(int32))
|
||||
return compare_and_swap_32((volatile int32*) ptr, (int32)comparand, (int32)replacement);
|
||||
return compare_and_swap_32((volatile int32*) ptr,
|
||||
(int32)comparand, (int32)replacement);
|
||||
else if (sizeof(T) == sizeof(int64))
|
||||
return compare_and_swap_64((volatile int64*) ptr, (int64)comparand, (int64)replacement);
|
||||
return compare_and_swap_64((volatile int64*) ptr,
|
||||
(int64)comparand, (int64)replacement);
|
||||
else
|
||||
_GLIBCXX_PARALLEL_ASSERT(false);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ template<typename RandomAccessIterator1,
|
|||
typename RandomAccessIterator2,
|
||||
typename Pred,
|
||||
typename Selector>
|
||||
std::pair<RandomAccessIterator1, RandomAccessIterator2>
|
||||
inline std::pair<RandomAccessIterator1, RandomAccessIterator2>
|
||||
find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
|
||||
RandomAccessIterator2 begin2, Pred pred, Selector selector)
|
||||
{
|
||||
|
@ -70,13 +70,13 @@ template<typename RandomAccessIterator1,
|
|||
{
|
||||
case Settings::GROWING_BLOCKS:
|
||||
return find_template(begin1, end1, begin2, pred, selector,
|
||||
growing_blocks_tag());
|
||||
growing_blocks_tag());
|
||||
case Settings::CONSTANT_SIZE_BLOCKS:
|
||||
return find_template(begin1, end1, begin2, pred, selector,
|
||||
constant_size_blocks_tag());
|
||||
constant_size_blocks_tag());
|
||||
case Settings::EQUAL_SPLIT:
|
||||
return find_template(begin1, end1, begin2, pred, selector,
|
||||
equal_split_tag());
|
||||
equal_split_tag());
|
||||
default:
|
||||
_GLIBCXX_PARALLEL_ASSERT(false);
|
||||
return std::make_pair(begin1, begin2);
|
||||
|
@ -158,8 +158,9 @@ template<typename RandomAccessIterator1,
|
|||
omp_destroy_lock(&result_lock);
|
||||
delete[] borders;
|
||||
|
||||
return std::pair<RandomAccessIterator1, RandomAccessIterator2>(
|
||||
begin1 + result, begin2 + result);
|
||||
return
|
||||
std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
|
||||
begin2 + result);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -205,8 +206,8 @@ template<typename RandomAccessIterator1,
|
|||
|
||||
difference_type length = end1 - begin1;
|
||||
|
||||
difference_type sequential_search_size = std::min<difference_type>(
|
||||
length, Settings::find_sequential_search_size);
|
||||
difference_type sequential_search_size =
|
||||
std::min<difference_type>(length, Settings::find_sequential_search_size);
|
||||
|
||||
// Try it sequentially first.
|
||||
std::pair<RandomAccessIterator1, RandomAccessIterator2> find_seq_result =
|
||||
|
@ -267,23 +268,25 @@ template<typename RandomAccessIterator1,
|
|||
omp_unset_lock(&result_lock);
|
||||
}
|
||||
|
||||
block_size = std::min<difference_type>(
|
||||
block_size * Settings::find_increasing_factor,
|
||||
Settings::find_maximum_block_size);
|
||||
block_size =
|
||||
std::min<difference_type>(block_size
|
||||
* Settings::find_increasing_factor,
|
||||
Settings::find_maximum_block_size);
|
||||
|
||||
// Get new block, update pointer to next block.
|
||||
start =
|
||||
fetch_and_add<difference_type>(&next_block_start, block_size);
|
||||
stop = (length < (start + block_size)) ?
|
||||
length : (start + block_size);
|
||||
fetch_and_add<difference_type>(&next_block_start, block_size);
|
||||
stop = ((length < (start + block_size))
|
||||
? length : (start + block_size));
|
||||
}
|
||||
} //parallel
|
||||
|
||||
omp_destroy_lock(&result_lock);
|
||||
|
||||
// Return iterator on found element.
|
||||
return std::pair<RandomAccessIterator1, RandomAccessIterator2>(
|
||||
begin1 + result, begin2 + result);
|
||||
return
|
||||
std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
|
||||
begin2 + result);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -391,8 +394,9 @@ template<typename RandomAccessIterator1,
|
|||
omp_destroy_lock(&result_lock);
|
||||
|
||||
// Return iterator on found element.
|
||||
return std::pair<RandomAccessIterator1, RandomAccessIterator2>(
|
||||
begin1 + result, begin2 + result);
|
||||
return
|
||||
std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
|
||||
begin2 + result);
|
||||
}
|
||||
#endif
|
||||
} // end namespace
|
||||
|
|
|
@ -57,231 +57,234 @@ namespace __gnu_parallel
|
|||
|
||||
/** @brief std::for_each() selector. */
|
||||
template<typename It>
|
||||
struct for_each_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
o(*i);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct for_each_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
o(*i);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief std::generate() selector. */
|
||||
template<typename It>
|
||||
struct generate_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
*i = o();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct generate_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
*i = o();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief std::fill() selector. */
|
||||
template<typename It>
|
||||
struct fill_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param v Current value.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Val>
|
||||
bool
|
||||
operator()(Val& v, It i)
|
||||
{
|
||||
*i = v;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct fill_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param v Current value.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Val>
|
||||
bool
|
||||
operator()(Val& v, It i)
|
||||
{
|
||||
*i = v;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief std::transform() selector, one input sequence variant. */
|
||||
template<typename It>
|
||||
struct transform1_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
*i.second = o(*i.first);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct transform1_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
*i.second = o(*i.first);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief std::transform() selector, two input sequences variant. */
|
||||
template<typename It>
|
||||
struct transform2_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
*i.third = o(*i.first, *i.second);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct transform2_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
*i.third = o(*i.first, *i.second);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief std::replace() selector. */
|
||||
template<typename It, typename T>
|
||||
struct replace_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Value to replace with. */
|
||||
const T& new_val;
|
||||
|
||||
/** @brief Constructor
|
||||
* @param new_val Value to replace with. */
|
||||
explicit replace_selector(const T &new_val) : new_val(new_val) {}
|
||||
|
||||
/** @brief Functor execution.
|
||||
* @param v Current value.
|
||||
* @param i Iterator referencing object. */
|
||||
bool
|
||||
operator()(T& v, It i)
|
||||
struct replace_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
if (*i == v)
|
||||
*i = new_val;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/** @brief Value to replace with. */
|
||||
const T& new_val;
|
||||
|
||||
/** @brief Constructor
|
||||
* @param new_val Value to replace with. */
|
||||
explicit
|
||||
replace_selector(const T &new_val) : new_val(new_val) {}
|
||||
|
||||
/** @brief Functor execution.
|
||||
* @param v Current value.
|
||||
* @param i Iterator referencing object. */
|
||||
bool
|
||||
operator()(T& v, It i)
|
||||
{
|
||||
if (*i == v)
|
||||
*i = new_val;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief std::replace() selector. */
|
||||
template<typename It, typename Op, typename T>
|
||||
struct replace_if_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Value to replace with. */
|
||||
const T& new_val;
|
||||
|
||||
/** @brief Constructor.
|
||||
* @param new_val Value to replace with. */
|
||||
explicit replace_if_selector(const T &new_val) : new_val(new_val) { }
|
||||
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
struct replace_if_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
if (o(*i))
|
||||
*i = new_val;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/** @brief Value to replace with. */
|
||||
const T& new_val;
|
||||
|
||||
/** @brief Constructor.
|
||||
* @param new_val Value to replace with. */
|
||||
explicit
|
||||
replace_if_selector(const T &new_val) : new_val(new_val) { }
|
||||
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object. */
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
if (o(*i))
|
||||
*i = new_val;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief std::count() selector. */
|
||||
template<typename It, typename Diff>
|
||||
struct count_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param v Current value.
|
||||
* @param i Iterator referencing object.
|
||||
* @return 1 if count, 0 if does not count. */
|
||||
template<typename Val>
|
||||
Diff
|
||||
operator()(Val& v, It i)
|
||||
{ return (v == *i) ? 1 : 0; }
|
||||
};
|
||||
struct count_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param v Current value.
|
||||
* @param i Iterator referencing object.
|
||||
* @return 1 if count, 0 if does not count. */
|
||||
template<typename Val>
|
||||
Diff
|
||||
operator()(Val& v, It i)
|
||||
{ return (v == *i) ? 1 : 0; }
|
||||
};
|
||||
|
||||
/** @brief std::count_if () selector. */
|
||||
template<typename It, typename Diff>
|
||||
struct count_if_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object.
|
||||
* @return 1 if count, 0 if does not count. */
|
||||
template<typename Op>
|
||||
Diff
|
||||
operator()(Op& o, It i)
|
||||
{ return (o(*i)) ? 1 : 0; }
|
||||
};
|
||||
struct count_if_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator.
|
||||
* @param i Iterator referencing object.
|
||||
* @return 1 if count, 0 if does not count. */
|
||||
template<typename Op>
|
||||
Diff
|
||||
operator()(Op& o, It i)
|
||||
{ return (o(*i)) ? 1 : 0; }
|
||||
};
|
||||
|
||||
/** @brief std::accumulate() selector. */
|
||||
template<typename It>
|
||||
struct accumulate_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator (unused).
|
||||
* @param i Iterator referencing object.
|
||||
* @return The current value. */
|
||||
template<typename Op>
|
||||
typename std::iterator_traits<It>::value_type operator()(Op o, It i)
|
||||
{ return *i; }
|
||||
};
|
||||
struct accumulate_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator (unused).
|
||||
* @param i Iterator referencing object.
|
||||
* @return The current value. */
|
||||
template<typename Op>
|
||||
typename std::iterator_traits<It>::value_type operator()(Op o, It i)
|
||||
{ return *i; }
|
||||
};
|
||||
|
||||
/** @brief std::inner_product() selector. */
|
||||
template<typename It, typename It2, typename T>
|
||||
struct inner_product_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Begin iterator of first sequence. */
|
||||
It begin1_iterator;
|
||||
struct inner_product_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Begin iterator of first sequence. */
|
||||
It begin1_iterator;
|
||||
|
||||
/** @brief Begin iterator of second sequence. */
|
||||
It2 begin2_iterator;
|
||||
/** @brief Begin iterator of second sequence. */
|
||||
It2 begin2_iterator;
|
||||
|
||||
/** @brief Constructor.
|
||||
* @param b1 Begin iterator of first sequence.
|
||||
* @param b2 Begin iterator of second sequence. */
|
||||
explicit inner_product_selector(It b1, It2 b2)
|
||||
: begin1_iterator(b1), begin2_iterator(b2) { }
|
||||
/** @brief Constructor.
|
||||
* @param b1 Begin iterator of first sequence.
|
||||
* @param b2 Begin iterator of second sequence. */
|
||||
explicit
|
||||
inner_product_selector(It b1, It2 b2)
|
||||
: begin1_iterator(b1), begin2_iterator(b2) { }
|
||||
|
||||
/** @brief Functor execution.
|
||||
* @param mult Multiplication functor.
|
||||
* @param current Iterator referencing object.
|
||||
* @return Inner product elemental result. */
|
||||
template<typename Op>
|
||||
T
|
||||
operator()(Op mult, It current)
|
||||
{
|
||||
typename std::iterator_traits<It>::difference_type position
|
||||
= current - begin1_iterator;
|
||||
return mult(*current, *(begin2_iterator + position));
|
||||
}
|
||||
};
|
||||
/** @brief Functor execution.
|
||||
* @param mult Multiplication functor.
|
||||
* @param current Iterator referencing object.
|
||||
* @return Inner product elemental result. */
|
||||
template<typename Op>
|
||||
T
|
||||
operator()(Op mult, It current)
|
||||
{
|
||||
typename std::iterator_traits<It>::difference_type position
|
||||
= current - begin1_iterator;
|
||||
return mult(*current, *(begin2_iterator + position));
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Selector that just returns the passed iterator. */
|
||||
template<typename It>
|
||||
struct identity_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator (unused).
|
||||
* @param i Iterator referencing object.
|
||||
* @return Passed iterator. */
|
||||
template<typename Op>
|
||||
It
|
||||
operator()(Op o, It i)
|
||||
{ return i; }
|
||||
};
|
||||
struct identity_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
/** @brief Functor execution.
|
||||
* @param o Operator (unused).
|
||||
* @param i Iterator referencing object.
|
||||
* @return Passed iterator. */
|
||||
template<typename Op>
|
||||
It
|
||||
operator()(Op o, It i)
|
||||
{ return i; }
|
||||
};
|
||||
|
||||
/** @brief Selector that returns the difference between two adjacent
|
||||
* elements.
|
||||
*/
|
||||
template<typename It>
|
||||
struct adjacent_difference_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
typename It::first_type go_back_one = i.first;
|
||||
--go_back_one;
|
||||
*i.second = o(*i.first, *go_back_one);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct adjacent_difference_selector : public generic_for_each_selector<It>
|
||||
{
|
||||
template<typename Op>
|
||||
bool
|
||||
operator()(Op& o, It i)
|
||||
{
|
||||
typename It::first_type go_back_one = i.first;
|
||||
--go_back_one;
|
||||
*i.second = o(*i.first, *go_back_one);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// XXX move into type_traits?
|
||||
/** @brief Functor doing nothing
|
||||
|
@ -308,55 +311,56 @@ namespace __gnu_parallel
|
|||
|
||||
/** @brief Reduction for finding the maximum element, using a comparator. */
|
||||
template<typename Comp, typename It>
|
||||
struct min_element_reduct
|
||||
{
|
||||
Comp& comp;
|
||||
|
||||
explicit min_element_reduct(Comp &c) : comp(c)
|
||||
{ }
|
||||
|
||||
It
|
||||
operator()(It x, It y)
|
||||
struct min_element_reduct
|
||||
{
|
||||
if (comp(*x, *y))
|
||||
return x;
|
||||
else
|
||||
return y;
|
||||
}
|
||||
};
|
||||
Comp& comp;
|
||||
|
||||
explicit
|
||||
min_element_reduct(Comp &c) : comp(c) { }
|
||||
|
||||
It
|
||||
operator()(It x, It y)
|
||||
{
|
||||
if (comp(*x, *y))
|
||||
return x;
|
||||
else
|
||||
return y;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Reduction for finding the maximum element, using a comparator. */
|
||||
template<typename Comp, typename It>
|
||||
struct max_element_reduct
|
||||
{
|
||||
Comp& comp;
|
||||
|
||||
explicit max_element_reduct(Comp& c) : comp(c)
|
||||
{ }
|
||||
|
||||
It
|
||||
operator()(It x, It y)
|
||||
struct max_element_reduct
|
||||
{
|
||||
if (comp(*x, *y))
|
||||
return y;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
};
|
||||
Comp& comp;
|
||||
|
||||
explicit
|
||||
max_element_reduct(Comp& c) : comp(c) { }
|
||||
|
||||
It
|
||||
operator()(It x, It y)
|
||||
{
|
||||
if (comp(*x, *y))
|
||||
return y;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief General reduction, using a binary operator. */
|
||||
template<typename BinOp>
|
||||
struct accumulate_binop_reduct
|
||||
{
|
||||
BinOp& binop;
|
||||
struct accumulate_binop_reduct
|
||||
{
|
||||
BinOp& binop;
|
||||
|
||||
explicit accumulate_binop_reduct(BinOp& b) : binop(b) {}
|
||||
explicit
|
||||
accumulate_binop_reduct(BinOp& b) : binop(b) { }
|
||||
|
||||
template<typename Result, typename Addend>
|
||||
Result
|
||||
operator()(const Result& x, const Addend& y)
|
||||
{ return binop(x, y); }
|
||||
};
|
||||
template<typename Result, typename Addend>
|
||||
Result
|
||||
operator()(const Result& x, const Addend& y)
|
||||
{ return binop(x, y); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -159,7 +159,7 @@ namespace __gnu_parallel
|
|||
// Smallest partitions.
|
||||
for (int i = 1; i < (num_parts + 1 - size_greater); ++i)
|
||||
{
|
||||
lengths[i-1] = size_part * range_length;
|
||||
lengths[i - 1] = size_part * range_length;
|
||||
index += size_part;
|
||||
starts[i] = os_starts[index];
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ namespace __gnu_parallel
|
|||
// Biggest partitions.
|
||||
for (int i = num_parts + 1 - size_greater; i <= num_parts; ++i)
|
||||
{
|
||||
lengths[i-1] = (size_part+1) * range_length;
|
||||
lengths[i - 1] = (size_part+1) * range_length;
|
||||
index += (size_part+1);
|
||||
starts[i] = os_starts[index];
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
size = _size;
|
||||
offset = size;
|
||||
losers = new Loser[size];
|
||||
for (unsigned int l = 0; l < size; l++)
|
||||
for (unsigned int l = 0; l < size; ++l)
|
||||
{
|
||||
//losers[l].key = ... stays unset
|
||||
losers[l].inf = true;
|
||||
|
@ -156,9 +156,10 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
bool inf = false;
|
||||
for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
|
||||
{
|
||||
if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup &&
|
||||
((comp(losers[pos].key, key)) ||
|
||||
(!comp(key, losers[pos].key) && losers[pos].source < source)))
|
||||
if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
|
||||
&& ((comp(losers[pos].key, key))
|
||||
|| (!comp(key, losers[pos].key)
|
||||
&& losers[pos].source < source)))
|
||||
|| losers[pos].inf || sup)
|
||||
{
|
||||
// Take next key.
|
||||
|
@ -186,8 +187,9 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
|
||||
{
|
||||
if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
|
||||
&& ((comp(losers[pos].key, key)) ||
|
||||
(!comp(key, losers[pos].key) && losers[pos].source < source)))
|
||||
&& ((comp(losers[pos].key, key))
|
||||
|| (!comp(key, losers[pos].key)
|
||||
&& losers[pos].source < source)))
|
||||
|| losers[pos].inf || sup)
|
||||
{
|
||||
std::swap(losers[pos].key, key);
|
||||
|
@ -285,9 +287,9 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
{
|
||||
unsigned int left = init_winner (2 * root);
|
||||
unsigned int right = init_winner (2 * root + 1);
|
||||
if (losers[right].sup ||
|
||||
(!losers[left].sup
|
||||
&& !comp(losers[right].key, losers[left].key)))
|
||||
if (losers[right].sup
|
||||
|| (!losers[left].sup
|
||||
&& !comp(losers[right].key, losers[left].key)))
|
||||
{
|
||||
// Left one is less or equal.
|
||||
losers[root] = losers[right];
|
||||
|
@ -345,7 +347,7 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
unsigned int right = init_winner (2 * root + 1);
|
||||
if (losers[right].sup
|
||||
|| (!losers[left].sup
|
||||
&& !comp(losers[right].key, losers[left].key)))
|
||||
&& !comp(losers[right].key, losers[left].key)))
|
||||
{
|
||||
// Left one is less or equal.
|
||||
losers[root] = losers[right];
|
||||
|
@ -443,7 +445,7 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
#ifndef COPY
|
||||
keys = new T[ik];
|
||||
#endif
|
||||
for (unsigned int i = ik - 1; i < k; i++)
|
||||
for (unsigned int i = ik - 1; i < k; ++i)
|
||||
losers[i + k].sup = true;
|
||||
}
|
||||
|
||||
|
@ -569,11 +571,11 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
|
||||
{
|
||||
// The smaller one gets promoted, ties are broken by source.
|
||||
if ( (sup && (!losers[pos].sup || losers[pos].source < source)) ||
|
||||
(!sup && !losers[pos].sup &&
|
||||
((comp(KEY(pos), KEY_SOURCE(source))) ||
|
||||
(!comp(KEY_SOURCE(source), KEY(pos))
|
||||
&& losers[pos].source < source))))
|
||||
if ((sup && (!losers[pos].sup || losers[pos].source < source))
|
||||
|| (!sup && !losers[pos].sup
|
||||
&& ((comp(KEY(pos), KEY_SOURCE(source)))
|
||||
|| (!comp(KEY_SOURCE(source), KEY(pos))
|
||||
&& losers[pos].source < source))))
|
||||
{
|
||||
// The other one is smaller.
|
||||
std::swap(losers[pos].sup, sup);
|
||||
|
@ -629,7 +631,7 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
k = 1 << (log2(ik - 1) + 1);
|
||||
offset = k;
|
||||
losers = new Loser[k * 2];
|
||||
for (unsigned int i = ik - 1; i < k; i++)
|
||||
for (unsigned int i = ik - 1; i < k; ++i)
|
||||
losers[i + k].sup = true;
|
||||
}
|
||||
|
||||
|
@ -746,11 +748,11 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
|
||||
{
|
||||
// The smaller one gets promoted, ties are broken by source.
|
||||
if ( (sup && (!losers[pos].sup || losers[pos].source < source)) ||
|
||||
(!sup && !losers[pos].sup &&
|
||||
((comp(*losers[pos].keyp, *keyp)) ||
|
||||
(!comp(*keyp, *losers[pos].keyp)
|
||||
&& losers[pos].source < source))))
|
||||
if ( (sup && (!losers[pos].sup || losers[pos].source < source))
|
||||
|| (!sup && !losers[pos].sup &&
|
||||
((comp(*losers[pos].keyp, *keyp))
|
||||
|| (!comp(*keyp, *losers[pos].keyp)
|
||||
&& losers[pos].source < source))))
|
||||
{
|
||||
// The other one is smaller.
|
||||
std::swap(losers[pos].sup, sup);
|
||||
|
@ -995,8 +997,8 @@ template<typename T, typename Comparator = std::less<T> >
|
|||
// Next greater or equal power of 2.
|
||||
unsigned int division = 1 << (log2(end - begin - 1));
|
||||
unsigned int left = init_winner(2 * root, begin, begin + division);
|
||||
unsigned int right
|
||||
= init_winner(2 * root + 1, begin + division, end);
|
||||
unsigned int right = init_winner(2 * root + 1,
|
||||
begin + division, end);
|
||||
if (!comp(*losers[right].keyp, *losers[left].keyp))
|
||||
{
|
||||
// Left one is less or equal.
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace __gnu_parallel
|
|||
*target++ = *begin2++;
|
||||
else
|
||||
*target++ = *begin1++;
|
||||
max_length--;
|
||||
--max_length;
|
||||
}
|
||||
|
||||
if (begin1 != end1)
|
||||
|
@ -143,8 +143,8 @@ namespace __gnu_parallel
|
|||
|
||||
*target = element1;
|
||||
|
||||
target++;
|
||||
max_length--;
|
||||
++target;
|
||||
--max_length;
|
||||
}
|
||||
if (begin1 != end1)
|
||||
{
|
||||
|
|
|
@ -212,7 +212,7 @@ namespace __gnu_parallel
|
|||
difference_type localrank = rank * m / N ;
|
||||
|
||||
int j;
|
||||
for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); j++)
|
||||
for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); ++j)
|
||||
a[sample[j].second] += n + 1;
|
||||
for (; j < m; j++)
|
||||
b[sample[j].second] -= n + 1;
|
||||
|
@ -279,7 +279,7 @@ namespace __gnu_parallel
|
|||
if (b[i] < ns[i])
|
||||
pq.push(std::make_pair(S(i)[b[i]], i));
|
||||
|
||||
for (; skew != 0 && !pq.empty(); skew--)
|
||||
for (; skew != 0 && !pq.empty(); --skew)
|
||||
{
|
||||
int source = pq.top().second;
|
||||
pq.pop();
|
||||
|
@ -302,7 +302,7 @@ namespace __gnu_parallel
|
|||
if (a[i] > 0)
|
||||
pq.push(std::make_pair(S(i)[a[i] - 1], i));
|
||||
|
||||
for (; skew != 0; skew++)
|
||||
for (; skew != 0; ++skew)
|
||||
{
|
||||
int source = pq.top().second;
|
||||
pq.pop();
|
||||
|
@ -416,7 +416,7 @@ namespace __gnu_parallel
|
|||
|
||||
ns[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second);
|
||||
nmax = ns[0];
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int i = 0; i < m; ++i)
|
||||
{
|
||||
ns[i] = std::distance(begin_seqs[i].first, begin_seqs[i].second);
|
||||
nmax = std::max(nmax, ns[i]);
|
||||
|
@ -431,7 +431,7 @@ namespace __gnu_parallel
|
|||
// From now on, including padding.
|
||||
N = l * m;
|
||||
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int i = 0; i < m; ++i)
|
||||
{
|
||||
a[i] = 0;
|
||||
b[i] = l;
|
||||
|
@ -460,9 +460,9 @@ namespace __gnu_parallel
|
|||
difference_type localrank = rank * m / N ;
|
||||
|
||||
int j;
|
||||
for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); j++)
|
||||
for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); ++j)
|
||||
a[sample[j].second] += n + 1;
|
||||
for (; j < m; j++)
|
||||
for (; j < m; ++j)
|
||||
b[sample[j].second] -= n + 1;
|
||||
|
||||
// Further refinement.
|
||||
|
@ -471,7 +471,7 @@ namespace __gnu_parallel
|
|||
n /= 2;
|
||||
|
||||
const T* lmax = NULL;
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int i = 0; i < m; ++i)
|
||||
{
|
||||
if (a[i] > 0)
|
||||
{
|
||||
|
@ -496,7 +496,7 @@ namespace __gnu_parallel
|
|||
}
|
||||
|
||||
difference_type leftsize = 0, total = 0;
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int i = 0; i < m; ++i)
|
||||
{
|
||||
leftsize += a[i] / (n + 1);
|
||||
total += l / (n + 1);
|
||||
|
@ -512,7 +512,7 @@ namespace __gnu_parallel
|
|||
std::vector<std::pair<T, int> >,
|
||||
lexicographic_reverse<T, int, Comparator> > pq(lrcomp);
|
||||
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int i = 0; i < m; ++i)
|
||||
if (b[i] < ns[i])
|
||||
pq.push(std::make_pair(S(i)[b[i]], i));
|
||||
|
||||
|
@ -535,7 +535,7 @@ namespace __gnu_parallel
|
|||
std::vector<std::pair<T, int> >,
|
||||
lexicographic<T, int, Comparator> > pq(lcomp);
|
||||
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int i = 0; i < m; ++i)
|
||||
if (a[i] > 0)
|
||||
pq.push(std::make_pair(S(i)[a[i] - 1], i));
|
||||
|
||||
|
@ -566,7 +566,7 @@ namespace __gnu_parallel
|
|||
|
||||
// Impossible to avoid the warning?
|
||||
T maxleft, minright;
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int i = 0; i < m; ++i)
|
||||
{
|
||||
if (a[i] > 0)
|
||||
{
|
||||
|
@ -610,7 +610,7 @@ namespace __gnu_parallel
|
|||
// We have to calculate an offset.
|
||||
offset = 0;
|
||||
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int i = 0; i < m; ++i)
|
||||
{
|
||||
difference_type lb = std::lower_bound(S(i), S(i) + ns[i],
|
||||
minright,
|
||||
|
|
|
@ -73,7 +73,7 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
template<typename RandomAccessIterator, typename Comparator>
|
||||
inline bool
|
||||
operator<=(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
|
||||
/** @brief Iterator wrapper supporting an implicit supremum at the end
|
||||
of the sequence, dominating all comparisons.
|
||||
|
@ -99,14 +99,14 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
* @param end End iterator of sequence.
|
||||
* @param comp Comparator provided for associated overloaded
|
||||
* compare operators. */
|
||||
inline guarded_iterator(RandomAccessIterator begin,
|
||||
RandomAccessIterator end, Comparator& comp)
|
||||
guarded_iterator(RandomAccessIterator begin,
|
||||
RandomAccessIterator end, Comparator& comp)
|
||||
: current(begin), end(end), comp(comp)
|
||||
{ }
|
||||
|
||||
/** @brief Pre-increment operator.
|
||||
* @return This. */
|
||||
inline guarded_iterator<RandomAccessIterator, Comparator>&
|
||||
guarded_iterator<RandomAccessIterator, Comparator>&
|
||||
operator++()
|
||||
{
|
||||
++current;
|
||||
|
@ -115,24 +115,24 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
|
||||
/** @brief Dereference operator.
|
||||
* @return Referenced element. */
|
||||
inline typename std::iterator_traits<RandomAccessIterator>::value_type
|
||||
typename std::iterator_traits<RandomAccessIterator>::value_type
|
||||
operator*()
|
||||
{ return *current; }
|
||||
|
||||
/** @brief Convert to wrapped iterator.
|
||||
* @return Wrapped iterator. */
|
||||
inline operator RandomAccessIterator()
|
||||
operator RandomAccessIterator()
|
||||
{ return current; }
|
||||
|
||||
friend bool
|
||||
operator< <RandomAccessIterator, Comparator>(
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
|
||||
friend bool
|
||||
operator<= <RandomAccessIterator, Comparator>(
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
};
|
||||
|
||||
/** @brief Compare two elements referenced by guarded iterators.
|
||||
|
@ -158,7 +158,7 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
template<typename RandomAccessIterator, typename Comparator>
|
||||
inline bool
|
||||
operator<=(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi2)
|
||||
guarded_iterator<RandomAccessIterator, Comparator>& bi2)
|
||||
{
|
||||
if (bi2.current == bi2.end) //bi1 is sup
|
||||
return bi1.current != bi1.end; //bi2 is not sup
|
||||
|
@ -194,14 +194,14 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
* @param begin Begin iterator of sequence.
|
||||
* @param end Unused, only for compatibility.
|
||||
* @param comp Unused, only for compatibility. */
|
||||
inline unguarded_iterator(RandomAccessIterator begin,
|
||||
RandomAccessIterator end, Comparator& comp)
|
||||
unguarded_iterator(RandomAccessIterator begin,
|
||||
RandomAccessIterator end, Comparator& comp)
|
||||
: current(begin), comp(comp)
|
||||
{ }
|
||||
|
||||
/** @brief Pre-increment operator.
|
||||
* @return This. */
|
||||
inline unguarded_iterator<RandomAccessIterator, Comparator>&
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>&
|
||||
operator++()
|
||||
{
|
||||
++current;
|
||||
|
@ -210,25 +210,24 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
|
||||
/** @brief Dereference operator.
|
||||
* @return Referenced element. */
|
||||
inline typename std::iterator_traits<RandomAccessIterator>::value_type
|
||||
typename std::iterator_traits<RandomAccessIterator>::value_type
|
||||
operator*()
|
||||
{ return *current; }
|
||||
|
||||
/** @brief Convert to wrapped iterator.
|
||||
* @return Wrapped iterator. */
|
||||
inline
|
||||
operator RandomAccessIterator()
|
||||
{ return current; }
|
||||
|
||||
friend bool
|
||||
operator< <RandomAccessIterator, Comparator>(
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
|
||||
friend bool
|
||||
operator<= <RandomAccessIterator, Comparator>(
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
|
||||
unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
|
||||
};
|
||||
|
||||
/** @brief Compare two elements referenced by unguarded iterators.
|
||||
|
@ -399,18 +398,17 @@ template<typename RandomAccessIteratorIterator, typename Comparator>
|
|||
* @param length Maximum length to merge.
|
||||
* @param stable Unused, stable anyway.
|
||||
* @return End iterator of output sequence. */
|
||||
template<
|
||||
template<typename RAI, typename C> class iterator,
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<template<typename RAI, typename C> class iterator,
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_3_variant(
|
||||
RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp, _DifferenceTp length, bool stable)
|
||||
multiway_merge_3_variant(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp, _DifferenceTp length,
|
||||
bool stable)
|
||||
{
|
||||
_GLIBCXX_CALL(length);
|
||||
|
||||
|
@ -483,11 +481,10 @@ template<
|
|||
return target;
|
||||
}
|
||||
|
||||
template<
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_3_combined(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -573,12 +570,11 @@ template<
|
|||
* @param length Maximum length to merge.
|
||||
* @param stable Unused, stable anyway.
|
||||
* @return End iterator of output sequence. */
|
||||
template<
|
||||
template<typename RAI, typename C> class iterator,
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<template<typename RAI, typename C> class iterator,
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -680,11 +676,10 @@ template<
|
|||
return target;
|
||||
}
|
||||
|
||||
template<
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_4_combined(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -765,11 +760,10 @@ template<
|
|||
* @param stable Stable merging incurs a performance penalty.
|
||||
* @return End iterator of output sequence.
|
||||
*/
|
||||
template<
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_bubble(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -845,7 +839,8 @@ template<
|
|||
++target;
|
||||
++(seqs_begin[source[0]].first);
|
||||
--length;
|
||||
if (seqs_begin[source[0]].first == seqs_begin[source[0]].second)
|
||||
if (seqs_begin[source[0]].first
|
||||
== seqs_begin[source[0]].second)
|
||||
{
|
||||
// Move everything to the left.
|
||||
for (int s = 0; s < nrs - 1; ++s)
|
||||
|
@ -870,7 +865,8 @@ template<
|
|||
++target;
|
||||
++(seqs_begin[source[0]].first);
|
||||
--length;
|
||||
if (seqs_begin[source[0]].first == seqs_begin[source[0]].second)
|
||||
if (seqs_begin[source[0]].first
|
||||
== seqs_begin[source[0]].second)
|
||||
{
|
||||
for (int s = 0; s < nrs - 1; ++s)
|
||||
{
|
||||
|
@ -888,9 +884,9 @@ template<
|
|||
|
||||
// Sink down.
|
||||
j = 1;
|
||||
while ((j < nrs) && (comp(fe[j], fe[j - 1]) ||
|
||||
(!comp(fe[j - 1], fe[j])
|
||||
&& (source[j] < source[j - 1]))))
|
||||
while ((j < nrs) && (comp(fe[j], fe[j - 1])
|
||||
|| (!comp(fe[j - 1], fe[j])
|
||||
&& (source[j] < source[j - 1]))))
|
||||
{
|
||||
std::swap(fe[j - 1], fe[j]);
|
||||
std::swap(source[j - 1], source[j]);
|
||||
|
@ -910,7 +906,8 @@ template<
|
|||
++target;
|
||||
++seqs_begin[source[0]].first;
|
||||
--length;
|
||||
if (seqs_begin[source[0]].first == seqs_begin[source[0]].second)
|
||||
if (seqs_begin[source[0]].first
|
||||
== seqs_begin[source[0]].second)
|
||||
{
|
||||
for (int s = 0; s < (nrs - 1); ++s)
|
||||
{
|
||||
|
@ -954,12 +951,11 @@ template<
|
|||
* @param stable Stable merging incurs a performance penalty.
|
||||
* @return End iterator of output sequence.
|
||||
*/
|
||||
template<
|
||||
typename LT,
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename LT,
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -987,7 +983,8 @@ template<
|
|||
|
||||
for (int t = 0; t < k; ++t)
|
||||
{
|
||||
if(arbitrary_element == NULL && _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
|
||||
if(arbitrary_element == NULL
|
||||
&& _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
|
||||
arbitrary_element = &(*seqs_begin[t].first);
|
||||
total_length += _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]);
|
||||
}
|
||||
|
@ -1074,11 +1071,10 @@ template<
|
|||
* @return End iterator of output sequence.
|
||||
* @pre No input will run out of elements during the merge.
|
||||
*/
|
||||
template<
|
||||
typename LT,
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp, typename Comparator>
|
||||
template<typename LT,
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp, typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_loser_tree_unguarded(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -1190,11 +1186,10 @@ template<
|
|||
return target;
|
||||
}
|
||||
|
||||
template<
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_loser_tree_combined(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -1254,17 +1249,16 @@ template<
|
|||
return target_end;
|
||||
}
|
||||
|
||||
template<
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_loser_tree_sentinel(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp,
|
||||
_DifferenceTp length, bool stable)
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp,
|
||||
_DifferenceTp length, bool stable)
|
||||
{
|
||||
_GLIBCXX_CALL(length)
|
||||
|
||||
|
@ -1326,7 +1320,8 @@ template<
|
|||
|
||||
/** @brief Sequential multi-way merging switch.
|
||||
*
|
||||
* The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and runtime settings.
|
||||
* The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and
|
||||
* runtime settings.
|
||||
* @param seqs_begin Begin iterator of iterator pair input sequence.
|
||||
* @param seqs_end End iterator of iterator pair input sequence.
|
||||
* @param target Begin iterator out output sequence.
|
||||
|
@ -1335,11 +1330,10 @@ template<
|
|||
* @param stable Stable merging incurs a performance penalty.
|
||||
* @param sentinel The sequences have a sentinel element.
|
||||
* @return End iterator of output sequence. */
|
||||
template<
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -1393,23 +1387,26 @@ template<
|
|||
{
|
||||
case Settings::LOSER_TREE_COMBINED:
|
||||
return_target = multiway_merge_3_combined(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length,
|
||||
stable);
|
||||
break;
|
||||
case Settings::LOSER_TREE_SENTINEL:
|
||||
return_target = multiway_merge_3_variant<unguarded_iterator>(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
return_target =
|
||||
multiway_merge_3_variant<unguarded_iterator>(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length,
|
||||
stable);
|
||||
break;
|
||||
default:
|
||||
return_target = multiway_merge_3_variant<guarded_iterator>(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
return_target =
|
||||
multiway_merge_3_variant<guarded_iterator>(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length,
|
||||
stable);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1417,25 +1414,25 @@ template<
|
|||
switch (mwma)
|
||||
{
|
||||
case Settings::LOSER_TREE_COMBINED:
|
||||
return_target = multiway_merge_4_combined(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
return_target = multiway_merge_4_combined(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
break;
|
||||
case Settings::LOSER_TREE_SENTINEL:
|
||||
return_target = multiway_merge_4_variant<unguarded_iterator>(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
return_target =
|
||||
multiway_merge_4_variant<unguarded_iterator>(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length,
|
||||
stable);
|
||||
break;
|
||||
default:
|
||||
return_target = multiway_merge_4_variant<guarded_iterator>(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1444,48 +1441,47 @@ template<
|
|||
switch (mwma)
|
||||
{
|
||||
case Settings::BUBBLE:
|
||||
return_target = multiway_merge_bubble(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
return_target = multiway_merge_bubble(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
break;
|
||||
#if _GLIBCXX_LOSER_TREE_EXPLICIT
|
||||
case Settings::LOSER_TREE_EXPLICIT:
|
||||
return_target = multiway_merge_loser_tree<
|
||||
LoserTreeExplicit<value_type, Comparator> >(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
LoserTreeExplicit<value_type, Comparator> >(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length,
|
||||
stable);
|
||||
break;
|
||||
#endif
|
||||
#if _GLIBCXX_LOSER_TREE
|
||||
case Settings::LOSER_TREE:
|
||||
return_target = multiway_merge_loser_tree<
|
||||
LoserTree<value_type, Comparator> >(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
LoserTree<value_type, Comparator> >(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length,
|
||||
stable);
|
||||
break;
|
||||
#endif
|
||||
#if _GLIBCXX_LOSER_TREE_COMBINED
|
||||
case Settings::LOSER_TREE_COMBINED:
|
||||
return_target = multiway_merge_loser_tree_combined(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
return_target = multiway_merge_loser_tree_combined(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length,
|
||||
stable);
|
||||
break;
|
||||
#endif
|
||||
#if _GLIBCXX_LOSER_TREE_SENTINEL
|
||||
case Settings::LOSER_TREE_SENTINEL:
|
||||
return_target = multiway_merge_loser_tree_sentinel(
|
||||
seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length, stable);
|
||||
return_target = multiway_merge_loser_tree_sentinel(seqs_begin,
|
||||
seqs_end,
|
||||
target,
|
||||
comp, length,
|
||||
stable);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -1504,7 +1500,8 @@ template<
|
|||
|
||||
/** @brief Parallel multi-way merge routine.
|
||||
*
|
||||
* The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and runtime settings.
|
||||
* The _GLIBCXX_PARALLEL_DECISION if based on the branching factor
|
||||
* and runtime settings.
|
||||
* @param seqs_begin Begin iterator of iterator pair input sequence.
|
||||
* @param seqs_end End iterator of iterator pair input sequence.
|
||||
* @param target Begin iterator out output sequence.
|
||||
|
@ -1514,11 +1511,10 @@ template<
|
|||
* @param sentinel Ignored.
|
||||
* @return End iterator of output sequence.
|
||||
*/
|
||||
template<
|
||||
typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
parallel_multiway_merge(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
|
@ -1553,7 +1549,7 @@ template<
|
|||
std::vector<std::pair<difference_type, difference_type> >* pieces;
|
||||
|
||||
thread_index_t num_threads = static_cast<thread_index_t>(
|
||||
std::min<difference_type>(get_max_threads(), total_length));
|
||||
std::min<difference_type>(get_max_threads(), total_length));
|
||||
|
||||
# pragma omp parallel num_threads (num_threads)
|
||||
{
|
||||
|
@ -1578,20 +1574,20 @@ template<
|
|||
for (difference_type i = 0; i < num_samples; ++i)
|
||||
{
|
||||
difference_type sample_index =
|
||||
static_cast<difference_type>(
|
||||
_GLIBCXX_PARALLEL_LENGTH(seqs_begin[s]) * (double(i + 1) /
|
||||
(num_samples + 1)) * (double(length)
|
||||
/ total_length));
|
||||
::new(&(samples[s * num_samples + i])) value_type(
|
||||
seqs_begin[s].first[sample_index]);
|
||||
static_cast<difference_type>(
|
||||
_GLIBCXX_PARALLEL_LENGTH(seqs_begin[s])
|
||||
* (double(i + 1) / (num_samples + 1))
|
||||
* (double(length) / total_length));
|
||||
::new(&(samples[s * num_samples + i]))
|
||||
value_type(seqs_begin[s].first[sample_index]);
|
||||
}
|
||||
|
||||
if (stable)
|
||||
__gnu_sequential::stable_sort(
|
||||
samples, samples + (num_samples * k), comp);
|
||||
__gnu_sequential::stable_sort(samples, samples
|
||||
+ (num_samples * k), comp);
|
||||
else
|
||||
__gnu_sequential::sort(
|
||||
samples, samples + (num_samples * k), comp);
|
||||
__gnu_sequential::sort(samples, samples
|
||||
+ (num_samples * k), comp);
|
||||
|
||||
for (int slab = 0; slab < num_threads; ++slab)
|
||||
// For each slab / processor.
|
||||
|
@ -1600,12 +1596,12 @@ template<
|
|||
// For each sequence.
|
||||
if (slab > 0)
|
||||
pieces[slab][seq].first =
|
||||
std::upper_bound(
|
||||
seqs_begin[seq].first,
|
||||
seqs_begin[seq].second,
|
||||
samples[num_samples * k * slab / num_threads],
|
||||
comp)
|
||||
- seqs_begin[seq].first;
|
||||
std::upper_bound(seqs_begin[seq].first,
|
||||
seqs_begin[seq].second,
|
||||
samples[num_samples * k
|
||||
* slab / num_threads],
|
||||
comp)
|
||||
- seqs_begin[seq].first;
|
||||
else
|
||||
{
|
||||
// Absolute beginning.
|
||||
|
@ -1613,14 +1609,15 @@ template<
|
|||
}
|
||||
if ((slab + 1) < num_threads)
|
||||
pieces[slab][seq].second =
|
||||
std::upper_bound(
|
||||
seqs_begin[seq].first,
|
||||
seqs_begin[seq].second,
|
||||
samples[num_samples * k * (slab + 1) /
|
||||
num_threads], comp)
|
||||
- seqs_begin[seq].first;
|
||||
std::upper_bound(seqs_begin[seq].first,
|
||||
seqs_begin[seq].second,
|
||||
samples[num_samples * k
|
||||
* (slab + 1)
|
||||
/ num_threads], comp)
|
||||
- seqs_begin[seq].first;
|
||||
else
|
||||
pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
|
||||
pieces[slab][seq].second
|
||||
= _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
|
||||
}
|
||||
::operator delete(samples);
|
||||
}
|
||||
|
@ -1651,8 +1648,9 @@ template<
|
|||
{
|
||||
offsets[num_threads - 1].resize(k);
|
||||
multiseq_partition(se.begin(), se.end(),
|
||||
difference_type(length),
|
||||
offsets[num_threads - 1].begin(), comp);
|
||||
difference_type(length),
|
||||
offsets[num_threads - 1].begin(),
|
||||
comp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1673,12 +1671,12 @@ template<
|
|||
pieces[slab - 1][seq].second;
|
||||
if (!tight || slab < (num_threads - 1))
|
||||
pieces[slab][seq].second =
|
||||
offsets[slab][seq] - seqs_begin[seq].first;
|
||||
offsets[slab][seq] - seqs_begin[seq].first;
|
||||
else
|
||||
{
|
||||
// slab == num_threads - 1
|
||||
pieces[slab][seq].second =
|
||||
_GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
|
||||
_GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1703,8 +1701,8 @@ template<
|
|||
for (int s = 0; s < k; ++s)
|
||||
{
|
||||
chunks[s] = std::make_pair(
|
||||
seqs_begin[s].first + pieces[iam][s].first,
|
||||
seqs_begin[s].first + pieces[iam][s].second);
|
||||
seqs_begin[s].first + pieces[iam][s].first,
|
||||
seqs_begin[s].first + pieces[iam][s].second);
|
||||
local_length += _GLIBCXX_PARALLEL_LENGTH(chunks[s]);
|
||||
}
|
||||
|
||||
|
@ -1721,13 +1719,13 @@ template<
|
|||
begin0 = seqs_begin[0].first + pieces[iam][0].first,
|
||||
begin1 = seqs_begin[1].first + pieces[iam][1].first;
|
||||
merge_advance(begin0,
|
||||
seqs_begin[0].first + pieces[iam][0].second,
|
||||
begin1,
|
||||
seqs_begin[1].first + pieces[iam][1].second,
|
||||
target + target_position,
|
||||
(pieces[iam][0].second - pieces[iam][0].first) +
|
||||
(pieces[iam][1].second - pieces[iam][1].first),
|
||||
comp);
|
||||
seqs_begin[0].first + pieces[iam][0].second,
|
||||
begin1,
|
||||
seqs_begin[1].first + pieces[iam][1].second,
|
||||
target + target_position,
|
||||
(pieces[iam][0].second - pieces[iam][0].first) +
|
||||
(pieces[iam][1].second - pieces[iam][1].first),
|
||||
comp);
|
||||
}
|
||||
} //parallel
|
||||
|
||||
|
@ -1754,11 +1752,10 @@ template<
|
|||
* @param stable Stable merging incurs a performance penalty.
|
||||
* @return End iterator of output sequence.
|
||||
*/
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorPairIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin,
|
||||
RandomAccessIteratorPairIterator seqs_end,
|
||||
|
@ -1775,13 +1772,13 @@ template<
|
|||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >= Settings::multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >= Settings::multiway_merge_minimal_n)))
|
||||
target_end = parallel_multiway_merge(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp, static_cast<difference_type>(length), stable, false);
|
||||
target_end = parallel_multiway_merge(seqs_begin, seqs_end,
|
||||
target, comp,
|
||||
static_cast<difference_type>(length),
|
||||
stable, false);
|
||||
else
|
||||
target_end = multiway_merge(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp, length, stable, false, sequential_tag());
|
||||
target_end = multiway_merge(seqs_begin, seqs_end, target, comp, length,
|
||||
stable, false, sequential_tag());
|
||||
|
||||
return target_end;
|
||||
}
|
||||
|
@ -1797,11 +1794,10 @@ template<
|
|||
* @pre For each @c i, @c seqs_begin[i].second must be the end
|
||||
* marker of the sequence, but also reference the one more sentinel
|
||||
* element. */
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
template<typename RandomAccessIteratorPairIterator,
|
||||
typename RandomAccessIterator3,
|
||||
typename _DifferenceTp,
|
||||
typename Comparator>
|
||||
RandomAccessIterator3
|
||||
multiway_merge_sentinel(RandomAccessIteratorPairIterator seqs_begin,
|
||||
RandomAccessIteratorPairIterator seqs_end,
|
||||
|
@ -1824,9 +1820,9 @@ template<
|
|||
seqs_begin, seqs_end,
|
||||
target, comp, static_cast<difference_type>(length), stable, true);
|
||||
else
|
||||
return multiway_merge(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp, length, stable, true, sequential_tag());
|
||||
return multiway_merge(seqs_begin, seqs_end,
|
||||
target, comp, length, stable,
|
||||
true, sequential_tag());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ template<typename RandomAccessIterator>
|
|||
* @param num_samples Number of samples to select.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename _DifferenceTp>
|
||||
inline void
|
||||
void
|
||||
determine_samples(PMWMSSortingData<RandomAccessIterator>* sd,
|
||||
_DifferenceTp& num_samples)
|
||||
{
|
||||
|
@ -138,9 +138,9 @@ template<typename RandomAccessIterator, typename _DifferenceTp>
|
|||
equally_split(sd->starts[iam + 1] - sd->starts[iam],
|
||||
num_samples + 1, es);
|
||||
|
||||
for (difference_type i = 0; i < num_samples; i++)
|
||||
::new(&(sd->samples[iam * num_samples + i])) value_type(
|
||||
sd->source[sd->starts[iam] + es[i + 1]]);
|
||||
for (difference_type i = 0; i < num_samples; ++i)
|
||||
::new(&(sd->samples[iam * num_samples + i]))
|
||||
value_type(sd->source[sd->starts[iam] + es[i + 1]]);
|
||||
|
||||
delete[] es;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ template<typename RandomAccessIterator, typename _DifferenceTp>
|
|||
* @param comp Comparator.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename Comparator>
|
||||
inline void
|
||||
void
|
||||
parallel_sort_mwms_pu(PMWMSSortingData<RandomAccessIterator>* sd,
|
||||
Comparator& comp)
|
||||
{
|
||||
|
@ -209,7 +209,7 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
|
||||
# pragma omp barrier
|
||||
|
||||
for (int s = 0; s < sd->num_threads; s++)
|
||||
for (int s = 0; s < sd->num_threads; ++s)
|
||||
{
|
||||
// For each sequence.
|
||||
if (num_samples * iam > 0)
|
||||
|
@ -243,7 +243,7 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
|
||||
std::vector<std::pair<SortingPlacesIterator, SortingPlacesIterator> >
|
||||
seqs(sd->num_threads);
|
||||
for (int s = 0; s < sd->num_threads; s++)
|
||||
for (int s = 0; s < sd->num_threads; ++s)
|
||||
seqs[s] = std::make_pair(sd->sorting_places[s],
|
||||
sd->sorting_places[s]
|
||||
+ (sd->starts[s + 1] - sd->starts[s]));
|
||||
|
@ -255,20 +255,20 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
multiseq_partition(seqs.begin(), seqs.end(),
|
||||
sd->starts[iam + 1], offsets.begin(), comp);
|
||||
|
||||
for (int seq = 0; seq < sd->num_threads; seq++)
|
||||
for (int seq = 0; seq < sd->num_threads; ++seq)
|
||||
{
|
||||
// for each sequence
|
||||
if (iam < (sd->num_threads - 1))
|
||||
sd->pieces[iam][seq].end = offsets[seq] - seqs[seq].first;
|
||||
else
|
||||
// very end of this sequence
|
||||
sd->pieces[iam][seq].end =
|
||||
sd->starts[seq + 1] - sd->starts[seq];
|
||||
sd->pieces[iam][seq].end = (sd->starts[seq + 1]
|
||||
- sd->starts[seq]);
|
||||
}
|
||||
|
||||
# pragma omp barrier
|
||||
|
||||
for (int seq = 0; seq < sd->num_threads; seq++)
|
||||
for (int seq = 0; seq < sd->num_threads; ++seq)
|
||||
{
|
||||
// For each sequence.
|
||||
if (iam > 0)
|
||||
|
@ -281,7 +281,7 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
|
||||
// Offset from target begin, length after merging.
|
||||
difference_type offset = 0, length_am = 0;
|
||||
for (int s = 0; s < sd->num_threads; s++)
|
||||
for (int s = 0; s < sd->num_threads; ++s)
|
||||
{
|
||||
length_am += sd->pieces[iam][s].end - sd->pieces[iam][s].begin;
|
||||
offset += sd->pieces[iam][s].begin;
|
||||
|
@ -293,8 +293,8 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
// instead of the assignment operator.
|
||||
// XXX incorrect (de)construction
|
||||
sd->merging_places[iam] = sd->temporaries[iam] =
|
||||
static_cast<value_type*>(
|
||||
::operator new(sizeof(value_type) * length_am));
|
||||
static_cast<value_type*>(::operator new(sizeof(value_type)
|
||||
* length_am));
|
||||
#else
|
||||
// Merge directly to target.
|
||||
sd->merging_places[iam] = sd->source + offset;
|
||||
|
@ -302,11 +302,11 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
std::vector<std::pair<SortingPlacesIterator, SortingPlacesIterator> >
|
||||
seqs(sd->num_threads);
|
||||
|
||||
for (int s = 0; s < sd->num_threads; s++)
|
||||
for (int s = 0; s < sd->num_threads; ++s)
|
||||
{
|
||||
seqs[s] =
|
||||
std::make_pair(sd->sorting_places[s] + sd->pieces[iam][s].begin,
|
||||
sd->sorting_places[s] + sd->pieces[iam][s].end);
|
||||
std::make_pair(sd->sorting_places[s] + sd->pieces[iam][s].begin,
|
||||
sd->sorting_places[s] + sd->pieces[iam][s].end);
|
||||
}
|
||||
|
||||
multiway_merge(seqs.begin(), seqs.end(), sd->merging_places[iam], comp,
|
||||
|
@ -333,13 +333,11 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
* @param stable Stable sorting.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename Comparator>
|
||||
inline void
|
||||
void
|
||||
parallel_sort_mwms(RandomAccessIterator begin, RandomAccessIterator end,
|
||||
Comparator comp,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::difference_type n,
|
||||
int num_threads,
|
||||
bool stable)
|
||||
Comparator comp, typename
|
||||
std::iterator_traits<RandomAccessIterator>::
|
||||
difference_type n, int num_threads, bool stable)
|
||||
{
|
||||
_GLIBCXX_CALL(n)
|
||||
|
||||
|
@ -382,14 +380,14 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
(Settings::sort_mwms_oversampling * num_threads - 1)
|
||||
* num_threads;
|
||||
sd.samples = static_cast<value_type*>(
|
||||
::operator new(size * sizeof(value_type)));
|
||||
::operator new(size * sizeof(value_type)));
|
||||
}
|
||||
else
|
||||
sd.samples = NULL;
|
||||
|
||||
sd.offsets = new difference_type[num_threads - 1];
|
||||
sd.pieces = new std::vector<Piece<difference_type> >[num_threads];
|
||||
for (int s = 0; s < num_threads; s++)
|
||||
for (int s = 0; s < num_threads; ++s)
|
||||
sd.pieces[s].resize(num_threads);
|
||||
starts = sd.starts = new difference_type[num_threads + 1];
|
||||
sd.stable = stable;
|
||||
|
@ -397,7 +395,7 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
difference_type chunk_length = n / num_threads;
|
||||
difference_type split = n % num_threads;
|
||||
difference_type pos = 0;
|
||||
for (int i = 0; i < num_threads; i++)
|
||||
for (int i = 0; i < num_threads; ++i)
|
||||
{
|
||||
starts[i] = pos;
|
||||
pos += (i < split) ? (chunk_length + 1) : chunk_length;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -58,387 +58,449 @@ namespace __parallel
|
|||
{
|
||||
// Sequential fallback.
|
||||
template<typename InputIterator, typename T>
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
__gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::accumulate(begin, end, init); }
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
__gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::accumulate(begin, end, init); }
|
||||
|
||||
template<typename InputIterator, typename T, typename BinaryOperation>
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
BinaryOperation binary_op, __gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::accumulate(begin, end, init, binary_op); }
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
BinaryOperation binary_op, __gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::accumulate(begin, end, init, binary_op); }
|
||||
|
||||
// Sequential fallback for input iterator case.
|
||||
template<typename InputIterator, typename T, typename IteratorTag>
|
||||
inline T
|
||||
accumulate_switch(InputIterator begin, InputIterator end, T init, IteratorTag) { return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); }
|
||||
inline T
|
||||
accumulate_switch(InputIterator begin, InputIterator end,
|
||||
T init, IteratorTag)
|
||||
{ return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); }
|
||||
|
||||
template<typename InputIterator, typename T, typename BinaryOperation, typename IteratorTag>
|
||||
T
|
||||
accumulate_switch(InputIterator begin, InputIterator end, T init,
|
||||
BinaryOperation binary_op, IteratorTag)
|
||||
{
|
||||
return accumulate(begin, end, init, binary_op,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
template<typename InputIterator, typename T, typename BinaryOperation,
|
||||
typename IteratorTag>
|
||||
T
|
||||
accumulate_switch(InputIterator begin, InputIterator end, T init,
|
||||
BinaryOperation binary_op, IteratorTag)
|
||||
{ return accumulate(begin, end, init, binary_op,
|
||||
__gnu_parallel::sequential_tag()); }
|
||||
|
||||
// Parallel algorithm for random access iterators.
|
||||
template<typename _RandomAccessIterator, typename T, typename BinaryOperation>
|
||||
T
|
||||
accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end,
|
||||
T init, BinaryOperation binary_op,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_unbalanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::accumulate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
T res = init;
|
||||
__gnu_parallel::accumulate_selector<_RandomAccessIterator> my_selector;
|
||||
__gnu_parallel::for_each_template_random_access(begin, end, __gnu_parallel::nothing(), my_selector, __gnu_parallel::accumulate_binop_reduct<BinaryOperation>(binary_op), res, res, -1, parallelism_tag);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return accumulate(begin, end, init, binary_op,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
template<typename _RandomAccessIterator, typename T,
|
||||
typename BinaryOperation>
|
||||
T
|
||||
accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end,
|
||||
T init, BinaryOperation binary_op,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_unbalanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::accumulate_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
T res = init;
|
||||
__gnu_parallel::accumulate_selector<_RandomAccessIterator>
|
||||
my_selector;
|
||||
__gnu_parallel::
|
||||
for_each_template_random_access(begin, end,
|
||||
__gnu_parallel::nothing(),
|
||||
my_selector,
|
||||
__gnu_parallel::
|
||||
accumulate_binop_reduct
|
||||
<BinaryOperation>(binary_op),
|
||||
res, res, -1, parallelism_tag);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return accumulate(begin, end, init, binary_op,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
|
||||
// Public interface.
|
||||
template<typename InputIterator, typename T>
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef std::iterator_traits<InputIterator> iterator_traits;
|
||||
typedef typename iterator_traits::value_type value_type;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef std::iterator_traits<InputIterator> iterator_traits;
|
||||
typedef typename iterator_traits::value_type value_type;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
|
||||
return accumulate_switch(begin, end, init, __gnu_parallel::plus<T, value_type>(),
|
||||
iterator_category(), parallelism_tag);
|
||||
}
|
||||
return accumulate_switch(begin, end, init,
|
||||
__gnu_parallel::plus<T, value_type>(),
|
||||
iterator_category(), parallelism_tag);
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename T>
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init)
|
||||
{
|
||||
typedef std::iterator_traits<InputIterator> iterator_traits;
|
||||
typedef typename iterator_traits::value_type value_type;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init)
|
||||
{
|
||||
typedef std::iterator_traits<InputIterator> iterator_traits;
|
||||
typedef typename iterator_traits::value_type value_type;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
|
||||
return accumulate_switch(begin, end, init, __gnu_parallel::plus<T, value_type>(),
|
||||
iterator_category());
|
||||
}
|
||||
return accumulate_switch(begin, end, init,
|
||||
__gnu_parallel::plus<T, value_type>(),
|
||||
iterator_category());
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename T, typename BinaryOperation>
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
BinaryOperation binary_op,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> iterator_traits;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
return accumulate_switch(begin, end, init, binary_op,
|
||||
iterator_category(), parallelism_tag);
|
||||
}
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
BinaryOperation binary_op,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> iterator_traits;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
return accumulate_switch(begin, end, init, binary_op,
|
||||
iterator_category(), parallelism_tag);
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename T, typename BinaryOperation>
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
BinaryOperation binary_op)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> iterator_traits;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
return accumulate_switch(begin, end, init, binary_op,
|
||||
iterator_category());
|
||||
}
|
||||
inline T
|
||||
accumulate(InputIterator begin, InputIterator end, T init,
|
||||
BinaryOperation binary_op)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> iterator_traits;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
return accumulate_switch(begin, end, init, binary_op,
|
||||
iterator_category());
|
||||
}
|
||||
|
||||
|
||||
// Sequential fallback.
|
||||
template<typename InputIterator1, typename InputIterator2, typename T>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init, __gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init); }
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init,
|
||||
__gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init); }
|
||||
|
||||
template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init, BinaryFunction1 binary_op1,
|
||||
BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag)
|
||||
{
|
||||
return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init,
|
||||
binary_op1, binary_op2);
|
||||
}
|
||||
template<typename InputIterator1, typename InputIterator2, typename T,
|
||||
typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init, BinaryFunction1 binary_op1,
|
||||
BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init,
|
||||
binary_op1, binary_op2); }
|
||||
|
||||
// Parallel algorithm for random access iterators.
|
||||
template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
T
|
||||
inner_product_switch(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, T init, BinaryFunction1 binary_op1, BinaryFunction2 binary_op2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1) >= __gnu_parallel::Settings::accumulate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
T res = init;
|
||||
__gnu_parallel::inner_product_selector<RandomAccessIterator1, RandomAccessIterator2, T> my_selector(first1, first2);
|
||||
__gnu_parallel::for_each_template_random_access(first1, last1, binary_op2, my_selector, binary_op1, res, res, -1, parallelism_tag);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return inner_product(first1, last1, first2, init,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
template<typename RandomAccessIterator1, typename RandomAccessIterator2,
|
||||
typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
T
|
||||
inner_product_switch(RandomAccessIterator1 first1,
|
||||
RandomAccessIterator1 last1,
|
||||
RandomAccessIterator2 first2, T init,
|
||||
BinaryFunction1 binary_op1,
|
||||
BinaryFunction2 binary_op2,
|
||||
random_access_iterator_tag,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_unbalanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1)
|
||||
>= __gnu_parallel::Settings::
|
||||
accumulate_minimal_n
|
||||
&& __gnu_parallel::
|
||||
is_parallel(parallelism_tag)))
|
||||
{
|
||||
T res = init;
|
||||
__gnu_parallel::
|
||||
inner_product_selector<RandomAccessIterator1,
|
||||
RandomAccessIterator2, T> my_selector(first1, first2);
|
||||
__gnu_parallel::
|
||||
for_each_template_random_access(first1, last1, binary_op2,
|
||||
my_selector, binary_op1,
|
||||
res, res, -1, parallelism_tag);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return inner_product(first1, last1, first2, init,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
|
||||
// No parallelism for input iterators.
|
||||
template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2, typename IteratorTag1, typename IteratorTag2>
|
||||
inline T
|
||||
inner_product_switch(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init,
|
||||
BinaryFunction1 binary_op1, BinaryFunction2 binary_op2,
|
||||
IteratorTag1, IteratorTag2)
|
||||
{
|
||||
return inner_product(first1, last1, first2, init, binary_op1, binary_op2,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
template<typename InputIterator1, typename InputIterator2, typename T,
|
||||
typename BinaryFunction1, typename BinaryFunction2,
|
||||
typename IteratorTag1, typename IteratorTag2>
|
||||
inline T
|
||||
inner_product_switch(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init,
|
||||
BinaryFunction1 binary_op1,
|
||||
BinaryFunction2 binary_op2,
|
||||
IteratorTag1, IteratorTag2)
|
||||
{ return inner_product(first1, last1, first2, init,
|
||||
binary_op1, binary_op2,
|
||||
__gnu_parallel::sequential_tag()); }
|
||||
|
||||
template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init, BinaryFunction1 binary_op1,
|
||||
BinaryFunction2 binary_op2,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator1> traits1_type;
|
||||
typedef typename traits1_type::iterator_category iterator1_category;
|
||||
template<typename InputIterator1, typename InputIterator2, typename T,
|
||||
typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init, BinaryFunction1 binary_op1,
|
||||
BinaryFunction2 binary_op2,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator1> traits1_type;
|
||||
typedef typename traits1_type::iterator_category iterator1_category;
|
||||
|
||||
typedef iterator_traits<InputIterator2> traits2_type;
|
||||
typedef typename traits2_type::iterator_category iterator2_category;
|
||||
typedef iterator_traits<InputIterator2> traits2_type;
|
||||
typedef typename traits2_type::iterator_category iterator2_category;
|
||||
|
||||
return inner_product_switch(first1, last1, first2, init, binary_op1,
|
||||
binary_op2, iterator1_category(),
|
||||
iterator2_category(), parallelism_tag);
|
||||
}
|
||||
return inner_product_switch(first1, last1, first2, init, binary_op1,
|
||||
binary_op2, iterator1_category(),
|
||||
iterator2_category(), parallelism_tag);
|
||||
}
|
||||
|
||||
template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init, BinaryFunction1 binary_op1,
|
||||
BinaryFunction2 binary_op2)
|
||||
{
|
||||
typedef iterator_traits<InputIterator1> traits1_type;
|
||||
typedef typename traits1_type::iterator_category iterator1_category;
|
||||
template<typename InputIterator1, typename InputIterator2, typename T,
|
||||
typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init, BinaryFunction1 binary_op1,
|
||||
BinaryFunction2 binary_op2)
|
||||
{
|
||||
typedef iterator_traits<InputIterator1> traits1_type;
|
||||
typedef typename traits1_type::iterator_category iterator1_category;
|
||||
|
||||
typedef iterator_traits<InputIterator2> traits2_type;
|
||||
typedef typename traits2_type::iterator_category iterator2_category;
|
||||
typedef iterator_traits<InputIterator2> traits2_type;
|
||||
typedef typename traits2_type::iterator_category iterator2_category;
|
||||
|
||||
return inner_product_switch(first1, last1, first2, init, binary_op1,
|
||||
binary_op2, iterator1_category(),
|
||||
iterator2_category());
|
||||
}
|
||||
return inner_product_switch(first1, last1, first2, init, binary_op1,
|
||||
binary_op2, iterator1_category(),
|
||||
iterator2_category());
|
||||
}
|
||||
|
||||
template<typename InputIterator1, typename InputIterator2, typename T>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator1> traits_type1;
|
||||
typedef typename traits_type1::value_type value_type1;
|
||||
typedef iterator_traits<InputIterator2> traits_type2;
|
||||
typedef typename traits_type2::value_type value_type2;
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator1> traits_type1;
|
||||
typedef typename traits_type1::value_type value_type1;
|
||||
typedef iterator_traits<InputIterator2> traits_type2;
|
||||
typedef typename traits_type2::value_type value_type2;
|
||||
|
||||
typedef typename __gnu_parallel::multiplies<value_type1, value_type2>::result
|
||||
typedef typename
|
||||
__gnu_parallel::multiplies<value_type1, value_type2>::result
|
||||
multiplies_result_type;
|
||||
return inner_product(first1, last1, first2, init,
|
||||
return inner_product(first1, last1, first2, init,
|
||||
__gnu_parallel::plus<T, multiplies_result_type>(),
|
||||
__gnu_parallel::multiplies<value_type1, value_type2>(),
|
||||
__gnu_parallel::
|
||||
multiplies<value_type1, value_type2>(),
|
||||
parallelism_tag);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InputIterator1, typename InputIterator2, typename T>
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init)
|
||||
{
|
||||
typedef iterator_traits<InputIterator1> traits_type1;
|
||||
typedef typename traits_type1::value_type value_type1;
|
||||
typedef iterator_traits<InputIterator2> traits_type2;
|
||||
typedef typename traits_type2::value_type value_type2;
|
||||
inline T
|
||||
inner_product(InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, T init)
|
||||
{
|
||||
typedef iterator_traits<InputIterator1> traits_type1;
|
||||
typedef typename traits_type1::value_type value_type1;
|
||||
typedef iterator_traits<InputIterator2> traits_type2;
|
||||
typedef typename traits_type2::value_type value_type2;
|
||||
|
||||
typedef typename __gnu_parallel::multiplies<value_type1, value_type2>::result
|
||||
typedef typename
|
||||
__gnu_parallel::multiplies<value_type1, value_type2>::result
|
||||
multiplies_result_type;
|
||||
return inner_product(first1, last1, first2, init,
|
||||
return inner_product(first1, last1, first2, init,
|
||||
__gnu_parallel::plus<T, multiplies_result_type>(),
|
||||
__gnu_parallel::multiplies<value_type1, value_type2>());
|
||||
}
|
||||
__gnu_parallel::
|
||||
multiplies<value_type1, value_type2>());
|
||||
}
|
||||
|
||||
// Sequential fallback.
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
|
||||
__gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::partial_sum(begin, end, result); }
|
||||
inline OutputIterator
|
||||
partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
|
||||
__gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::partial_sum(begin, end, result); }
|
||||
|
||||
// Sequential fallback.
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
|
||||
BinaryOperation bin_op, __gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); }
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
|
||||
BinaryOperation bin_op, __gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); }
|
||||
|
||||
// Sequential fallback for input iterator case.
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation, typename IteratorTag1, typename IteratorTag2>
|
||||
inline OutputIterator
|
||||
partial_sum_switch(InputIterator begin, InputIterator end, OutputIterator result, BinaryOperation bin_op, IteratorTag1, IteratorTag2)
|
||||
{
|
||||
return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op);
|
||||
}
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation, typename IteratorTag1,
|
||||
typename IteratorTag2>
|
||||
inline OutputIterator
|
||||
partial_sum_switch(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
IteratorTag1, IteratorTag2)
|
||||
{ return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); }
|
||||
|
||||
// Parallel algorithm for random access iterators.
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||
OutputIterator
|
||||
partial_sum_switch(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
random_access_iterator_tag, random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::partial_sum_minimal_n))
|
||||
return __gnu_parallel::parallel_partial_sum(begin, end, result, bin_op);
|
||||
else
|
||||
return partial_sum(begin, end, result, bin_op, __gnu_parallel::sequential_tag());
|
||||
}
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
OutputIterator
|
||||
partial_sum_switch(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
random_access_iterator_tag, random_access_iterator_tag)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
|
||||
sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::
|
||||
partial_sum_minimal_n))
|
||||
return __gnu_parallel::parallel_partial_sum(begin, end,
|
||||
result, bin_op);
|
||||
else
|
||||
return partial_sum(begin, end, result, bin_op,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
|
||||
// Public interface.
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
partial_sum(InputIterator begin, InputIterator end, OutputIterator result)
|
||||
{
|
||||
typedef typename iterator_traits<InputIterator>::value_type value_type;
|
||||
return partial_sum(begin, end, result, std::plus<value_type>());
|
||||
}
|
||||
inline OutputIterator
|
||||
partial_sum(InputIterator begin, InputIterator end, OutputIterator result)
|
||||
{
|
||||
typedef typename iterator_traits<InputIterator>::value_type value_type;
|
||||
return partial_sum(begin, end, result, std::plus<value_type>());
|
||||
}
|
||||
|
||||
// Public interface
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
|
||||
BinaryOperation binary_op)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traitsi_type;
|
||||
typedef typename traitsi_type::iterator_category iteratori_category;
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
|
||||
BinaryOperation binary_op)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traitsi_type;
|
||||
typedef typename traitsi_type::iterator_category iteratori_category;
|
||||
|
||||
typedef iterator_traits<OutputIterator> traitso_type;
|
||||
typedef typename traitso_type::iterator_category iteratoro_category;
|
||||
typedef iterator_traits<OutputIterator> traitso_type;
|
||||
typedef typename traitso_type::iterator_category iteratoro_category;
|
||||
|
||||
return partial_sum_switch(begin, end, result, binary_op,
|
||||
iteratori_category(), iteratoro_category());
|
||||
}
|
||||
return partial_sum_switch(begin, end, result, binary_op,
|
||||
iteratori_category(), iteratoro_category());
|
||||
}
|
||||
|
||||
// Sequential fallback.
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, __gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::adjacent_difference(begin, end, result); }
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, __gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::adjacent_difference(begin, end, result); }
|
||||
|
||||
// Sequential fallback.
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
__gnu_parallel::sequential_tag)
|
||||
{
|
||||
return _GLIBCXX_STD_P::adjacent_difference(begin, end, result, bin_op);
|
||||
}
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
__gnu_parallel::sequential_tag)
|
||||
{ return _GLIBCXX_STD_P::adjacent_difference(begin, end, result, bin_op); }
|
||||
|
||||
// Sequential fallback for input iterator case.
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation, typename IteratorTag1, typename IteratorTag2>
|
||||
inline OutputIterator
|
||||
adjacent_difference_switch(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation, typename IteratorTag1,
|
||||
typename IteratorTag2>
|
||||
inline OutputIterator
|
||||
adjacent_difference_switch(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
IteratorTag1, IteratorTag2)
|
||||
{
|
||||
return adjacent_difference(begin, end, result, bin_op,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
{ return adjacent_difference(begin, end, result, bin_op,
|
||||
__gnu_parallel::sequential_tag()); }
|
||||
|
||||
// Parallel algorithm for random access iterators.
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||
OutputIterator
|
||||
adjacent_difference_switch(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
random_access_iterator_tag,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::adjacent_difference_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
bool dummy = true;
|
||||
typedef __gnu_parallel::iterator_pair<InputIterator, OutputIterator, random_access_iterator_tag> ip;
|
||||
*result = *begin;
|
||||
ip begin_pair(begin + 1, result + 1), end_pair(end, result + (end - begin));
|
||||
__gnu_parallel::adjacent_difference_selector<ip> functionality;
|
||||
__gnu_parallel::for_each_template_random_access(begin_pair, end_pair, bin_op, functionality, __gnu_parallel::dummy_reduct(), dummy, dummy, -1, parallelism_tag);
|
||||
return functionality.finish_iterator;
|
||||
}
|
||||
else
|
||||
return adjacent_difference(begin, end, result, bin_op,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
OutputIterator
|
||||
adjacent_difference_switch(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
random_access_iterator_tag,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism parallelism_tag
|
||||
= __gnu_parallel::parallel_balanced)
|
||||
{
|
||||
if (_GLIBCXX_PARALLEL_CONDITION(
|
||||
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
|
||||
>= __gnu_parallel::Settings::adjacent_difference_minimal_n
|
||||
&& __gnu_parallel::is_parallel(parallelism_tag)))
|
||||
{
|
||||
bool dummy = true;
|
||||
typedef __gnu_parallel::iterator_pair<InputIterator, OutputIterator,
|
||||
random_access_iterator_tag> ip;
|
||||
*result = *begin;
|
||||
ip begin_pair(begin + 1, result + 1),
|
||||
end_pair(end, result + (end - begin));
|
||||
__gnu_parallel::adjacent_difference_selector<ip> functionality;
|
||||
__gnu_parallel::
|
||||
for_each_template_random_access(begin_pair, end_pair, bin_op,
|
||||
functionality,
|
||||
__gnu_parallel::dummy_reduct(),
|
||||
dummy, dummy, -1, parallelism_tag);
|
||||
return functionality.finish_iterator;
|
||||
}
|
||||
else
|
||||
return adjacent_difference(begin, end, result, bin_op,
|
||||
__gnu_parallel::sequential_tag());
|
||||
}
|
||||
|
||||
// Public interface.
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
return adjacent_difference(begin, end, result, std::minus<value_type>(),
|
||||
parallelism_tag);
|
||||
}
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
return adjacent_difference(begin, end, result, std::minus<value_type>(),
|
||||
parallelism_tag);
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
return adjacent_difference(begin, end, result, std::minus<value_type>());
|
||||
}
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
return adjacent_difference(begin, end, result, std::minus<value_type>());
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation binary_op,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traitsi_type;
|
||||
typedef typename traitsi_type::iterator_category iteratori_category;
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation binary_op,
|
||||
__gnu_parallel::parallelism parallelism_tag)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traitsi_type;
|
||||
typedef typename traitsi_type::iterator_category iteratori_category;
|
||||
|
||||
typedef iterator_traits<OutputIterator> traitso_type;
|
||||
typedef typename traitso_type::iterator_category iteratoro_category;
|
||||
typedef iterator_traits<OutputIterator> traitso_type;
|
||||
typedef typename traitso_type::iterator_category iteratoro_category;
|
||||
|
||||
return adjacent_difference_switch(begin, end, result, binary_op,
|
||||
iteratori_category(),
|
||||
iteratoro_category(), parallelism_tag);
|
||||
}
|
||||
return adjacent_difference_switch(begin, end, result, binary_op,
|
||||
iteratori_category(),
|
||||
iteratoro_category(), parallelism_tag);
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation binary_op)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traitsi_type;
|
||||
typedef typename traitsi_type::iterator_category iteratori_category;
|
||||
template<typename InputIterator, typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
adjacent_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation binary_op)
|
||||
{
|
||||
typedef iterator_traits<InputIterator> traitsi_type;
|
||||
typedef typename traitsi_type::iterator_category iteratori_category;
|
||||
|
||||
typedef iterator_traits<OutputIterator> traitso_type;
|
||||
typedef typename traitso_type::iterator_category iteratoro_category;
|
||||
typedef iterator_traits<OutputIterator> traitso_type;
|
||||
typedef typename traitso_type::iterator_category iteratoro_category;
|
||||
|
||||
return adjacent_difference_switch(begin, end, result, binary_op,
|
||||
iteratori_category(),
|
||||
iteratoro_category());
|
||||
}
|
||||
return adjacent_difference_switch(begin, end, result, binary_op,
|
||||
iteratori_category(),
|
||||
iteratoro_category());
|
||||
}
|
||||
} // end namespace
|
||||
} // end namespace
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// <numeric> parallel extensions -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -44,146 +44,162 @@ namespace std
|
|||
{
|
||||
namespace __parallel
|
||||
{
|
||||
template<typename _IIter, typename T>
|
||||
inline T
|
||||
accumulate(_IIter, _IIter, T);
|
||||
template<typename _IIter, typename _Tp>
|
||||
_Tp
|
||||
accumulate(_IIter, _IIter, _Tp);
|
||||
|
||||
template<typename _IIter, typename T>
|
||||
inline T
|
||||
accumulate(_IIter, _IIter, T, __gnu_parallel::sequential_tag);
|
||||
template<typename _IIter, typename _Tp>
|
||||
_Tp
|
||||
accumulate(_IIter, _IIter, _Tp, __gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter, typename T>
|
||||
inline T
|
||||
accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism parallelism_tag);
|
||||
template<typename _IIter, typename _Tp>
|
||||
_Tp
|
||||
accumulate(_IIter, _IIter, _Tp, __gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter, typename T, typename _Tag>
|
||||
inline T
|
||||
accumulate_switch(_IIter, _IIter, T, _Tag);
|
||||
template<typename _IIter, typename _Tp, typename _Tag>
|
||||
_Tp
|
||||
accumulate_switch(_IIter, _IIter, _Tp, _Tag);
|
||||
|
||||
template<typename _IIter, typename T, typename _BinaryOper>
|
||||
inline T
|
||||
accumulate(_IIter, _IIter, T, _BinaryOper);
|
||||
template<typename _IIter, typename _Tp, typename _BinaryOper>
|
||||
_Tp
|
||||
accumulate(_IIter, _IIter, _Tp, _BinaryOper);
|
||||
|
||||
template<typename _IIter, typename T, typename _BinaryOper>
|
||||
inline T
|
||||
accumulate(_IIter, _IIter, T, _BinaryOper, __gnu_parallel::sequential_tag);
|
||||
template<typename _IIter, typename _Tp, typename _BinaryOper>
|
||||
_Tp
|
||||
accumulate(_IIter, _IIter, _Tp, _BinaryOper,
|
||||
__gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter, typename T, typename _BinaryOper>
|
||||
inline T
|
||||
accumulate(_IIter, _IIter, T, _BinaryOper,
|
||||
__gnu_parallel::parallelism parallelism_tag);
|
||||
template<typename _IIter, typename _Tp, typename _BinaryOper>
|
||||
_Tp
|
||||
accumulate(_IIter, _IIter, _Tp, _BinaryOper,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter, typename T, typename _BinaryOper, typename _Tag>
|
||||
T
|
||||
accumulate_switch(_IIter, _IIter, T, _BinaryOper, _Tag);
|
||||
template<typename _IIter, typename _Tp, typename _BinaryOper,
|
||||
typename _Tag>
|
||||
_Tp
|
||||
accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag);
|
||||
|
||||
template<typename _RAIter, typename T, typename _BinaryOper>
|
||||
T
|
||||
accumulate_switch(_RAIter, _RAIter, T, _BinaryOper,
|
||||
random_access_iterator_tag, __gnu_parallel::parallelism);
|
||||
|
||||
|
||||
template<typename _IIter, typename _OIter>
|
||||
inline _OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
inline _OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper);
|
||||
|
||||
template<typename _IIter, typename _OIter>
|
||||
inline _OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
inline _OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
__gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter, typename _OIter>
|
||||
inline _OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
inline _OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
template<typename _RAIter, typename _Tp, typename _BinaryOper>
|
||||
_Tp
|
||||
accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper, typename _Tag1, typename _Tag2>
|
||||
inline _OIter
|
||||
adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
|
||||
template<typename _IIter, typename _OIter>
|
||||
_OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
_OIter
|
||||
adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
random_access_iterator_tag,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism);
|
||||
_OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper);
|
||||
|
||||
template<typename _IIter, typename _OIter>
|
||||
_OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter,
|
||||
__gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
_OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
__gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter, typename _OIter>
|
||||
_OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
_OIter
|
||||
adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper,
|
||||
typename _Tag1, typename _Tag2>
|
||||
_OIter
|
||||
adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
_Tag1, _Tag2);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
_OIter
|
||||
adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
random_access_iterator_tag,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename _Tp>
|
||||
_Tp
|
||||
inner_product(_IIter1, _IIter1, _IIter2, _Tp);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename _Tp>
|
||||
_Tp
|
||||
inner_product(_IIter1, _IIter1, _IIter2, _Tp,
|
||||
__gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename _Tp>
|
||||
_Tp
|
||||
inner_product(_IIter1, _IIter1, _IIter2, _Tp,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename _Tp,
|
||||
typename _BinaryFunction1, typename _BinaryFunction2>
|
||||
_Tp
|
||||
inner_product(_IIter1, _IIter1, _IIter2, _Tp,
|
||||
_BinaryFunction1, _BinaryFunction2);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename _Tp,
|
||||
typename _BinaryFunction1, typename _BinaryFunction2>
|
||||
_Tp
|
||||
inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1,
|
||||
_BinaryFunction2, __gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename _Tp,
|
||||
typename BinaryFunction1, typename BinaryFunction2>
|
||||
_Tp
|
||||
inner_product(_IIter1, _IIter1, _IIter2, _Tp, BinaryFunction1,
|
||||
BinaryFunction2, __gnu_parallel::parallelism);
|
||||
|
||||
template<typename _RAIter1, typename _RAIter2, typename _Tp,
|
||||
typename BinaryFunction1, typename BinaryFunction2>
|
||||
_Tp
|
||||
inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1,
|
||||
BinaryFunction2, random_access_iterator_tag,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename _Tp,
|
||||
typename _BinaryFunction1, typename _BinaryFunction2,
|
||||
typename _Tag1, typename _Tag2>
|
||||
_Tp
|
||||
inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1,
|
||||
_BinaryFunction2, _Tag1, _Tag2);
|
||||
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename T>
|
||||
inline T
|
||||
inner_product(_IIter1, _IIter1, _IIter2, T);
|
||||
template<typename _IIter, typename _OIter>
|
||||
_OIter
|
||||
partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename T>
|
||||
inline T
|
||||
inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename T>
|
||||
inline T
|
||||
inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::parallelism);
|
||||
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2,
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
_OIter
|
||||
partial_sum(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
__gnu_parallel::sequential_tag);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
inline T
|
||||
inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _RAIter1, typename _RAIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
|
||||
T
|
||||
inner_product_switch(_RAIter1, _RAIter1, _RAIter2, T, BinaryFunction1,
|
||||
BinaryFunction2, random_access_iterator_tag,
|
||||
random_access_iterator_tag,
|
||||
__gnu_parallel::parallelism);
|
||||
|
||||
template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2, typename _Tag1, typename _Tag2>
|
||||
inline T
|
||||
inner_product_switch(_IIter1, _IIter1, _IIter2, T, BinaryFunction1,
|
||||
BinaryFunction2, _Tag1, _Tag2);
|
||||
|
||||
|
||||
template<typename _IIter, typename _OIter>
|
||||
inline _OIter
|
||||
partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag);
|
||||
_OIter
|
||||
partial_sum(_IIter, _IIter, _OIter result);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
inline _OIter
|
||||
partial_sum(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag);
|
||||
_OIter
|
||||
partial_sum(_IIter, _IIter, _OIter, _BinaryOper);
|
||||
|
||||
template<typename _IIter, typename _OIter>
|
||||
inline _OIter
|
||||
partial_sum(_IIter, _IIter, _OIter result);
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper,
|
||||
typename _Tag1, typename _Tag2>
|
||||
_OIter
|
||||
partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
inline _OIter
|
||||
partial_sum(_IIter, _IIter, _OIter, _BinaryOper);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper, typename _Tag1, typename _Tag2>
|
||||
inline _OIter
|
||||
partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
|
||||
|
||||
template<typename _IIter, typename _OIter, typename _BinaryOper>
|
||||
_OIter
|
||||
partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag);
|
||||
_OIter
|
||||
partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper,
|
||||
random_access_iterator_tag, random_access_iterator_tag);
|
||||
} // end namespace
|
||||
} // end namespace
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -65,17 +65,18 @@ namespace __gnu_parallel
|
|||
* @return User-supplied functor (that may contain a part of the result).
|
||||
*/
|
||||
template<typename RandomAccessIterator,
|
||||
typename Op,
|
||||
typename Fu,
|
||||
typename Red,
|
||||
typename Result>
|
||||
typename Op,
|
||||
typename Fu,
|
||||
typename Red,
|
||||
typename Result>
|
||||
Op
|
||||
for_each_template_random_access_omp_loop(
|
||||
RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Op o, Fu& f, Red r, Result base, Result& output,
|
||||
typename std::iterator_traits<RandomAccessIterator>::
|
||||
difference_type bound)
|
||||
for_each_template_random_access_omp_loop(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Op o, Fu& f, Red r, Result base,
|
||||
Result& output,
|
||||
typename std::iterator_traits
|
||||
<RandomAccessIterator>::
|
||||
difference_type bound)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
|
@ -83,7 +84,7 @@ template<typename RandomAccessIterator,
|
|||
|
||||
difference_type length = end - begin;
|
||||
thread_index_t num_threads =
|
||||
__gnu_parallel::min<difference_type>(get_max_threads(), length);
|
||||
__gnu_parallel::min<difference_type>(get_max_threads(), length);
|
||||
|
||||
Result *thread_results;
|
||||
|
||||
|
@ -94,19 +95,19 @@ template<typename RandomAccessIterator,
|
|||
num_threads = omp_get_num_threads();
|
||||
thread_results = new Result[num_threads];
|
||||
|
||||
for (thread_index_t i = 0; i < num_threads; i++)
|
||||
for (thread_index_t i = 0; i < num_threads; ++i)
|
||||
thread_results[i] = Result();
|
||||
}
|
||||
|
||||
thread_index_t iam = omp_get_thread_num();
|
||||
|
||||
# pragma omp for schedule(dynamic, Settings::workstealing_chunk_size)
|
||||
for (difference_type pos = 0; pos < length; pos++)
|
||||
for (difference_type pos = 0; pos < length; ++pos)
|
||||
thread_results[iam] =
|
||||
r(thread_results[iam], f(o, begin+pos));
|
||||
} //parallel
|
||||
|
||||
for (thread_index_t i = 0; i < num_threads; i++)
|
||||
for (thread_index_t i = 0; i < num_threads; ++i)
|
||||
output = r(output, thread_results[i]);
|
||||
|
||||
delete [] thread_results;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -65,25 +65,26 @@ namespace __gnu_parallel
|
|||
* @return User-supplied functor (that may contain a part of the result).
|
||||
*/
|
||||
template<typename RandomAccessIterator,
|
||||
typename Op,
|
||||
typename Fu,
|
||||
typename Red,
|
||||
typename Result>
|
||||
typename Op,
|
||||
typename Fu,
|
||||
typename Red,
|
||||
typename Result>
|
||||
Op
|
||||
for_each_template_random_access_omp_loop_static(
|
||||
RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Op o, Fu& f, Red r, Result base, Result& output,
|
||||
typename std::iterator_traits<RandomAccessIterator>::
|
||||
difference_type bound)
|
||||
for_each_template_random_access_omp_loop_static(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Op o, Fu& f, Red r,
|
||||
Result base, Result& output,
|
||||
typename std::iterator_traits
|
||||
<RandomAccessIterator>::
|
||||
difference_type bound)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
difference_type;
|
||||
std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
difference_type length = end - begin;
|
||||
thread_index_t num_threads =
|
||||
std::min<difference_type>(get_max_threads(), length);
|
||||
std::min<difference_type>(get_max_threads(), length);
|
||||
|
||||
Result *thread_results;
|
||||
|
||||
|
@ -94,20 +95,19 @@ template<typename RandomAccessIterator,
|
|||
num_threads = omp_get_num_threads();
|
||||
thread_results = new Result[num_threads];
|
||||
|
||||
for (thread_index_t i = 0; i < num_threads; i++)
|
||||
for (thread_index_t i = 0; i < num_threads; ++i)
|
||||
thread_results[i] = Result();
|
||||
}
|
||||
|
||||
thread_index_t iam = omp_get_thread_num();
|
||||
|
||||
# pragma omp for schedule(static, Settings::workstealing_chunk_size)
|
||||
for (difference_type pos = 0; pos < length; pos++)
|
||||
thread_results[iam] =
|
||||
r(thread_results[iam], f(o, begin+pos));
|
||||
for (difference_type pos = 0; pos < length; ++pos)
|
||||
thread_results[iam] = r(thread_results[iam], f(o, begin+pos));
|
||||
} //parallel
|
||||
|
||||
for (thread_index_t i = 0; i < num_threads; i++)
|
||||
output = r(output, thread_results[i]);
|
||||
for (thread_index_t i = 0; i < num_threads; ++i)
|
||||
output = r(output, thread_results[i]);
|
||||
|
||||
delete [] thread_results;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -64,19 +64,19 @@ namespace __gnu_parallel
|
|||
* std::count_n()).
|
||||
* @return User-supplied functor (that may contain a part of the result).
|
||||
*/
|
||||
template<
|
||||
typename RandomAccessIterator,
|
||||
typename Op,
|
||||
typename Fu,
|
||||
typename Red,
|
||||
typename Result>
|
||||
template<typename RandomAccessIterator,
|
||||
typename Op,
|
||||
typename Fu,
|
||||
typename Red,
|
||||
typename Result>
|
||||
Op
|
||||
for_each_template_random_access_ed(
|
||||
RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Op o, Fu& f, Red r, Result base, Result& output,
|
||||
typename std::iterator_traits<RandomAccessIterator>::
|
||||
difference_type bound)
|
||||
for_each_template_random_access_ed(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Op o, Fu& f, Red r, Result base,
|
||||
Result& output,
|
||||
typename std::iterator_traits
|
||||
<RandomAccessIterator>::
|
||||
difference_type bound)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
|
@ -85,7 +85,7 @@ template<
|
|||
Result *thread_results;
|
||||
|
||||
thread_index_t num_threads =
|
||||
__gnu_parallel::min<difference_type>(get_max_threads(), length);
|
||||
__gnu_parallel::min<difference_type>(get_max_threads(), length);
|
||||
|
||||
# pragma omp parallel num_threads(num_threads)
|
||||
{
|
||||
|
@ -116,7 +116,7 @@ template<
|
|||
thread_results[iam] = reduct;
|
||||
} //parallel
|
||||
|
||||
for (thread_index_t i = 0; i < num_threads; i++)
|
||||
for (thread_index_t i = 0; i < num_threads; ++i)
|
||||
output = r(output, thread_results[i]);
|
||||
|
||||
// Points to last element processed (needed as return value for
|
||||
|
|
|
@ -57,15 +57,14 @@ namespace __gnu_parallel
|
|||
* @param value Start value. Must be passed since the neutral
|
||||
* element is unknown in general.
|
||||
* @return End iterator of output sequence. */
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
inline OutputIterator
|
||||
parallel_partial_sum_basecase(
|
||||
InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
typename std::iterator_traits<InputIterator>::value_type value)
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
OutputIterator
|
||||
parallel_partial_sum_basecase(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
typename std::iterator_traits
|
||||
<InputIterator>::value_type value)
|
||||
{
|
||||
if (begin == end)
|
||||
return result;
|
||||
|
@ -90,15 +89,14 @@ template<
|
|||
* @param num_threads Number of threads to use.
|
||||
* @return End iterator of output sequence.
|
||||
*/
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
OutputIterator
|
||||
parallel_partial_sum_linear(
|
||||
InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
typename std::iterator_traits<InputIterator>::difference_type n)
|
||||
parallel_partial_sum_linear(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op,
|
||||
typename std::iterator_traits
|
||||
<InputIterator>::difference_type n)
|
||||
{
|
||||
typedef std::iterator_traits<InputIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
|
@ -133,9 +131,10 @@ template<
|
|||
else
|
||||
{
|
||||
difference_type chunk_length =
|
||||
((double)n /
|
||||
((double)num_threads + Settings::partial_sum_dilatation)),
|
||||
borderstart = n - num_threads * chunk_length;
|
||||
((double)n
|
||||
/ ((double)num_threads
|
||||
+ Settings::partial_sum_dilatation)),
|
||||
borderstart = n - num_threads * chunk_length;
|
||||
borders[0] = 0;
|
||||
for (int i = 1; i < (num_threads + 1); ++i)
|
||||
{
|
||||
|
@ -145,8 +144,8 @@ template<
|
|||
borders[num_threads + 1] = n;
|
||||
}
|
||||
|
||||
sums = static_cast<value_type*>(
|
||||
::operator new(sizeof(value_type) * num_threads));
|
||||
sums = static_cast<value_type*>(::operator new(sizeof(value_type)
|
||||
* num_threads));
|
||||
OutputIterator target_end;
|
||||
} //single
|
||||
|
||||
|
@ -155,16 +154,17 @@ template<
|
|||
{
|
||||
*result = *begin;
|
||||
parallel_partial_sum_basecase(begin + 1, begin + borders[1],
|
||||
result + 1, bin_op, *begin);
|
||||
result + 1, bin_op, *begin);
|
||||
::new(&(sums[iam])) value_type(*(result + borders[1] - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
::new(&(sums[iam])) value_type(
|
||||
std::accumulate(begin + borders[iam] + 1,
|
||||
begin + borders[iam + 1],
|
||||
*(begin + borders[iam]),
|
||||
bin_op, __gnu_parallel::sequential_tag()));
|
||||
::new(&(sums[iam]))
|
||||
value_type(std::accumulate(begin + borders[iam] + 1,
|
||||
begin + borders[iam + 1],
|
||||
*(begin + borders[iam]),
|
||||
bin_op,
|
||||
__gnu_parallel::sequential_tag()));
|
||||
}
|
||||
|
||||
# pragma omp barrier
|
||||
|
@ -177,9 +177,9 @@ template<
|
|||
|
||||
// Still same team.
|
||||
parallel_partial_sum_basecase(begin + borders[iam + 1],
|
||||
begin + borders[iam + 2],
|
||||
result + borders[iam + 1], bin_op,
|
||||
sums[iam]);
|
||||
begin + borders[iam + 2],
|
||||
result + borders[iam + 1], bin_op,
|
||||
sums[iam]);
|
||||
} //parallel
|
||||
|
||||
::operator delete(sums);
|
||||
|
@ -194,10 +194,9 @@ template<
|
|||
* @param result Begin iterator of output sequence.
|
||||
* @param bin_op Associative binary function.
|
||||
* @return End iterator of output sequence. */
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename BinaryOperation>
|
||||
OutputIterator
|
||||
parallel_partial_sum(InputIterator begin, InputIterator end,
|
||||
OutputIterator result, BinaryOperation bin_op)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -92,10 +92,11 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
reserved_right = new bool[num_threads];
|
||||
|
||||
if (Settings::partition_chunk_share > 0.0)
|
||||
chunk_size = std::max<difference_type>(
|
||||
Settings::partition_chunk_size,
|
||||
(double)n * Settings::partition_chunk_share /
|
||||
(double)num_threads);
|
||||
chunk_size = std::max<difference_type>(Settings::
|
||||
partition_chunk_size,
|
||||
(double)n * Settings::
|
||||
partition_chunk_share
|
||||
/ (double)num_threads);
|
||||
else
|
||||
chunk_size = Settings::partition_chunk_size;
|
||||
}
|
||||
|
@ -106,7 +107,7 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
{
|
||||
difference_type num_chunks = (right - left + 1) / chunk_size;
|
||||
|
||||
for (int r = 0; r < num_threads; r++)
|
||||
for (int r = 0; r < num_threads; ++r)
|
||||
{
|
||||
reserved_left[r] = false;
|
||||
reserved_right[r] = false;
|
||||
|
@ -164,10 +165,10 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
{
|
||||
while (pred(begin[thread_left])
|
||||
&& thread_left <= thread_left_border)
|
||||
thread_left++;
|
||||
++thread_left;
|
||||
while (!pred(begin[thread_right])
|
||||
&& thread_right >= thread_right_border)
|
||||
thread_right--;
|
||||
--thread_right;
|
||||
|
||||
if (thread_left > thread_left_border
|
||||
|| thread_right < thread_right_border)
|
||||
|
@ -175,18 +176,18 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
break;
|
||||
|
||||
std::swap(begin[thread_left], begin[thread_right]);
|
||||
thread_left++;
|
||||
thread_right--;
|
||||
++thread_left;
|
||||
--thread_right;
|
||||
}
|
||||
}
|
||||
|
||||
// Now swap the leftover chunks to the right places.
|
||||
if (thread_left <= thread_left_border)
|
||||
# pragma omp atomic
|
||||
leftover_left++;
|
||||
++leftover_left;
|
||||
if (thread_right >= thread_right_border)
|
||||
# pragma omp atomic
|
||||
leftover_right++;
|
||||
++leftover_right;
|
||||
|
||||
# pragma omp barrier
|
||||
|
||||
|
@ -212,9 +213,8 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
&& thread_right_border <= rightnew)
|
||||
{
|
||||
// Chunk already in place, reserve spot.
|
||||
reserved_right
|
||||
[((thread_right_border - 1) - right) / chunk_size]
|
||||
= true;
|
||||
reserved_right[((thread_right_border - 1) - right)
|
||||
/ chunk_size] = true;
|
||||
}
|
||||
|
||||
# pragma omp barrier
|
||||
|
@ -225,7 +225,7 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
// Find spot and swap.
|
||||
difference_type swapstart = -1;
|
||||
omp_set_lock(&result_lock);
|
||||
for (int r = 0; r < leftover_left; r++)
|
||||
for (int r = 0; r < leftover_left; ++r)
|
||||
if (!reserved_left[r])
|
||||
{
|
||||
reserved_left[r] = true;
|
||||
|
@ -238,10 +238,10 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
_GLIBCXX_PARALLEL_ASSERT(swapstart != -1);
|
||||
#endif
|
||||
|
||||
std::swap_ranges(
|
||||
begin + thread_left_border - (chunk_size - 1),
|
||||
begin + thread_left_border + 1,
|
||||
begin + swapstart);
|
||||
std::swap_ranges(begin + thread_left_border
|
||||
- (chunk_size - 1),
|
||||
begin + thread_left_border + 1,
|
||||
begin + swapstart);
|
||||
}
|
||||
|
||||
if (thread_right >= thread_right_border
|
||||
|
@ -250,7 +250,7 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
// Find spot and swap
|
||||
difference_type swapstart = -1;
|
||||
omp_set_lock(&result_lock);
|
||||
for (int r = 0; r < leftover_right; r++)
|
||||
for (int r = 0; r < leftover_right; ++r)
|
||||
if (!reserved_right[r])
|
||||
{
|
||||
reserved_right[r] = true;
|
||||
|
@ -264,17 +264,17 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
#endif
|
||||
|
||||
std::swap_ranges(begin + thread_right_border,
|
||||
begin + thread_right_border + chunk_size,
|
||||
begin + swapstart);
|
||||
begin + thread_right_border + chunk_size,
|
||||
begin + swapstart);
|
||||
}
|
||||
#if _GLIBCXX_ASSERTIONS
|
||||
# pragma omp barrier
|
||||
|
||||
# pragma omp single
|
||||
{
|
||||
for (int r = 0; r < leftover_left; r++)
|
||||
for (int r = 0; r < leftover_left; ++r)
|
||||
_GLIBCXX_PARALLEL_ASSERT(reserved_left[r]);
|
||||
for (int r = 0; r < leftover_right; r++)
|
||||
for (int r = 0; r < leftover_right; ++r)
|
||||
_GLIBCXX_PARALLEL_ASSERT(reserved_right[r]);
|
||||
}
|
||||
|
||||
|
@ -295,17 +295,17 @@ template<typename RandomAccessIterator, typename Predicate>
|
|||
{
|
||||
// Go right until key is geq than pivot.
|
||||
while (pred(begin[final_left]) && final_left < final_right)
|
||||
final_left++;
|
||||
++final_left;
|
||||
|
||||
// Go left until key is less than pivot.
|
||||
while (!pred(begin[final_right]) && final_left < final_right)
|
||||
final_right--;
|
||||
--final_right;
|
||||
|
||||
if (final_left == final_right)
|
||||
break;
|
||||
std::swap(begin[final_left], begin[final_right]);
|
||||
final_left++;
|
||||
final_right--;
|
||||
++final_left;
|
||||
--final_right;
|
||||
}
|
||||
|
||||
// All elements on the left side are < piv, all elements on the
|
||||
|
@ -345,7 +345,8 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
RandomAccessIterator split;
|
||||
random_number rng;
|
||||
|
||||
difference_type minimum_length = std::max<difference_type>(2, Settings::partition_minimal_n);
|
||||
difference_type minimum_length =
|
||||
std::max<difference_type>(2, Settings::partition_minimal_n);
|
||||
|
||||
// Break if input range to small.
|
||||
while (static_cast<sequence_index_t>(end - begin) >= minimum_length)
|
||||
|
@ -359,15 +360,19 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
std::swap(*pivot_pos, *(end - 1));
|
||||
pivot_pos = end - 1;
|
||||
|
||||
// XXX Comparator must have first_value_type, second_value_type, result_type
|
||||
// Comparator == __gnu_parallel::lexicographic<S, int, __gnu_parallel::less<S, S> >
|
||||
// XXX Comparator must have first_value_type, second_value_type,
|
||||
// result_type
|
||||
// Comparator == __gnu_parallel::lexicographic<S, int,
|
||||
// __gnu_parallel::less<S, S> >
|
||||
// pivot_pos == std::pair<S, int>*
|
||||
// XXX binder2nd only for RandomAccessIterators??
|
||||
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool> pred(comp, *pivot_pos);
|
||||
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
|
||||
pred(comp, *pivot_pos);
|
||||
|
||||
// Divide, leave pivot unchanged in last place.
|
||||
RandomAccessIterator split_pos1, split_pos2;
|
||||
split_pos1 = begin + parallel_partition(begin, end - 1, pred, get_max_threads());
|
||||
split_pos1 = begin + parallel_partition(begin, end - 1, pred,
|
||||
get_max_threads());
|
||||
|
||||
// Left side: < pivot_pos; right side: >= pivot_pos
|
||||
|
||||
|
@ -377,14 +382,19 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
pivot_pos = split_pos1;
|
||||
|
||||
// In case all elements are equal, split_pos1 == 0
|
||||
if ((split_pos1 + 1 - begin) < (n >> 7) || (end - split_pos1) < (n >> 7))
|
||||
if ((split_pos1 + 1 - begin) < (n >> 7)
|
||||
|| (end - split_pos1) < (n >> 7))
|
||||
{
|
||||
// Very unequal split, one part smaller than one 128th
|
||||
// elements not stricly larger than the pivot.
|
||||
__gnu_parallel::unary_negate<__gnu_parallel::binder1st<Comparator, value_type, value_type, bool>, value_type> pred(__gnu_parallel::binder1st<Comparator, value_type, value_type, bool>(comp, *pivot_pos));
|
||||
__gnu_parallel::unary_negate<__gnu_parallel::
|
||||
binder1st<Comparator, value_type, value_type, bool>, value_type>
|
||||
pred(__gnu_parallel::binder1st<Comparator, value_type,
|
||||
value_type, bool>(comp, *pivot_pos));
|
||||
|
||||
// Find other end of pivot-equal range.
|
||||
split_pos2 = __gnu_sequential::partition(split_pos1 + 1, end, pred);
|
||||
split_pos2 = __gnu_sequential::partition(split_pos1 + 1,
|
||||
end, pred);
|
||||
}
|
||||
else
|
||||
// Only skip the pivot.
|
||||
|
@ -410,7 +420,9 @@ template<typename RandomAccessIterator, typename Comparator>
|
|||
* @param comp Comparator. */
|
||||
template<typename RandomAccessIterator, typename Comparator>
|
||||
void
|
||||
parallel_partial_sort(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end, Comparator comp)
|
||||
parallel_partial_sort(RandomAccessIterator begin,
|
||||
RandomAccessIterator middle,
|
||||
RandomAccessIterator end, Comparator comp)
|
||||
{
|
||||
parallel_nth_element(begin, middle, end, comp);
|
||||
std::sort(begin, middle, comp);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -55,96 +55,98 @@ namespace __gnu_parallel
|
|||
* Calling them would not make sense in a concurrent setting.
|
||||
* @param T Contained element type. */
|
||||
template<typename T>
|
||||
class RestrictedBoundedConcurrentQueue
|
||||
{
|
||||
private:
|
||||
/** @brief Array of elements, seen as cyclic buffer. */
|
||||
T* base;
|
||||
|
||||
/** @brief Maximal number of elements contained at the same time. */
|
||||
sequence_index_t max_size;
|
||||
|
||||
/** @brief Cyclic begin and end pointers contained in one
|
||||
atomically changeable value. */
|
||||
_GLIBCXX_VOLATILE lcas_t borders;
|
||||
|
||||
public:
|
||||
/** @brief Constructor. Not to be called concurrent, of course.
|
||||
* @param max_size Maximal number of elements to be contained. */
|
||||
RestrictedBoundedConcurrentQueue(sequence_index_t max_size)
|
||||
class RestrictedBoundedConcurrentQueue
|
||||
{
|
||||
this->max_size = max_size;
|
||||
base = new T[max_size];
|
||||
borders = encode2(0, 0);
|
||||
private:
|
||||
/** @brief Array of elements, seen as cyclic buffer. */
|
||||
T* base;
|
||||
|
||||
/** @brief Maximal number of elements contained at the same time. */
|
||||
sequence_index_t max_size;
|
||||
|
||||
/** @brief Cyclic begin and end pointers contained in one
|
||||
atomically changeable value. */
|
||||
_GLIBCXX_VOLATILE lcas_t borders;
|
||||
|
||||
public:
|
||||
/** @brief Constructor. Not to be called concurrent, of course.
|
||||
* @param max_size Maximal number of elements to be contained. */
|
||||
RestrictedBoundedConcurrentQueue(sequence_index_t max_size)
|
||||
{
|
||||
this->max_size = max_size;
|
||||
base = new T[max_size];
|
||||
borders = encode2(0, 0);
|
||||
#pragma omp flush
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Destructor. Not to be called concurrent, of course. */
|
||||
~RestrictedBoundedConcurrentQueue()
|
||||
{
|
||||
delete[] base;
|
||||
}
|
||||
/** @brief Destructor. Not to be called concurrent, of course. */
|
||||
~RestrictedBoundedConcurrentQueue()
|
||||
{ delete[] base; }
|
||||
|
||||
/** @brief Pushes one element into the queue at the front end.
|
||||
* Must not be called concurrently with pop_front(). */
|
||||
void push_front(const T& t)
|
||||
{
|
||||
lcas_t former_borders = borders;
|
||||
int former_front, former_back;
|
||||
decode2(former_borders, former_front, former_back);
|
||||
*(base + former_front % max_size) = t;
|
||||
/** @brief Pushes one element into the queue at the front end.
|
||||
* Must not be called concurrently with pop_front(). */
|
||||
void
|
||||
push_front(const T& t)
|
||||
{
|
||||
lcas_t former_borders = borders;
|
||||
int former_front, former_back;
|
||||
decode2(former_borders, former_front, former_back);
|
||||
*(base + former_front % max_size) = t;
|
||||
#if _GLIBCXX_ASSERTIONS
|
||||
// Otherwise: front - back > max_size eventually.
|
||||
_GLIBCXX_PARALLEL_ASSERT(((former_front + 1) - former_back) <= max_size);
|
||||
// Otherwise: front - back > max_size eventually.
|
||||
_GLIBCXX_PARALLEL_ASSERT(((former_front + 1) - former_back)
|
||||
<= max_size);
|
||||
#endif
|
||||
fetch_and_add(&borders, encode2(1, 0));
|
||||
}
|
||||
fetch_and_add(&borders, encode2(1, 0));
|
||||
}
|
||||
|
||||
/** @brief Pops one element from the queue at the front end.
|
||||
* Must not be called concurrently with pop_front(). */
|
||||
bool pop_front(T& t)
|
||||
{
|
||||
int former_front, former_back;
|
||||
/** @brief Pops one element from the queue at the front end.
|
||||
* Must not be called concurrently with pop_front(). */
|
||||
bool
|
||||
pop_front(T& t)
|
||||
{
|
||||
int former_front, former_back;
|
||||
#pragma omp flush
|
||||
decode2(borders, former_front, former_back);
|
||||
while (former_front > former_back)
|
||||
{
|
||||
// Chance.
|
||||
lcas_t former_borders = encode2(former_front, former_back);
|
||||
lcas_t new_borders = encode2(former_front - 1, former_back);
|
||||
if (compare_and_swap(&borders, former_borders, new_borders))
|
||||
{
|
||||
t = *(base + (former_front - 1) % max_size);
|
||||
return true;
|
||||
}
|
||||
decode2(borders, former_front, former_back);
|
||||
while (former_front > former_back)
|
||||
{
|
||||
// Chance.
|
||||
lcas_t former_borders = encode2(former_front, former_back);
|
||||
lcas_t new_borders = encode2(former_front - 1, former_back);
|
||||
if (compare_and_swap(&borders, former_borders, new_borders))
|
||||
{
|
||||
t = *(base + (former_front - 1) % max_size);
|
||||
return true;
|
||||
}
|
||||
#pragma omp flush
|
||||
decode2(borders, former_front, former_back);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
decode2(borders, former_front, former_back);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief Pops one element from the queue at the front end.
|
||||
* Must not be called concurrently with pop_front(). */
|
||||
bool pop_back(T& t) //queue behavior
|
||||
{
|
||||
int former_front, former_back;
|
||||
/** @brief Pops one element from the queue at the front end.
|
||||
* Must not be called concurrently with pop_front(). */
|
||||
bool
|
||||
pop_back(T& t) //queue behavior
|
||||
{
|
||||
int former_front, former_back;
|
||||
#pragma omp flush
|
||||
decode2(borders, former_front, former_back);
|
||||
while (former_front > former_back)
|
||||
{
|
||||
// Chance.
|
||||
lcas_t former_borders = encode2(former_front, former_back);
|
||||
lcas_t new_borders = encode2(former_front, former_back + 1);
|
||||
if (compare_and_swap(&borders, former_borders, new_borders))
|
||||
{
|
||||
t = *(base + former_back % max_size);
|
||||
return true;
|
||||
}
|
||||
decode2(borders, former_front, former_back);
|
||||
while (former_front > former_back)
|
||||
{
|
||||
// Chance.
|
||||
lcas_t former_borders = encode2(former_front, former_back);
|
||||
lcas_t new_borders = encode2(former_front, former_back + 1);
|
||||
if (compare_and_swap(&borders, former_borders, new_borders))
|
||||
{
|
||||
t = *(base + former_back % max_size);
|
||||
return true;
|
||||
}
|
||||
#pragma omp flush
|
||||
decode2(borders, former_front, former_back);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
decode2(borders, former_front, former_back);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} //namespace __gnu_parallel
|
||||
|
||||
|
|
|
@ -53,48 +53,46 @@ namespace __gnu_parallel
|
|||
* this part.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename Comparator>
|
||||
inline
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
parallel_sort_qs_divide(
|
||||
RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Comparator comp,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
pivot_rank,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
num_samples,
|
||||
thread_index_t num_threads)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
parallel_sort_qs_divide(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Comparator comp, typename std::iterator_traits
|
||||
<RandomAccessIterator>::difference_type pivot_rank,
|
||||
typename std::iterator_traits
|
||||
<RandomAccessIterator>::difference_type
|
||||
num_samples, thread_index_t num_threads)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
|
||||
difference_type n = end - begin;
|
||||
num_samples = std::min(num_samples, n);
|
||||
difference_type n = end - begin;
|
||||
num_samples = std::min(num_samples, n);
|
||||
|
||||
// Allocate uninitialized, to avoid default constructor.
|
||||
value_type* samples = static_cast<value_type*>(
|
||||
::operator new(num_samples * sizeof(value_type)));
|
||||
// Allocate uninitialized, to avoid default constructor.
|
||||
value_type* samples =
|
||||
static_cast<value_type*>(::operator new(num_samples
|
||||
* sizeof(value_type)));
|
||||
|
||||
for (difference_type s = 0; s < num_samples; ++s)
|
||||
{
|
||||
const unsigned long long index = static_cast<unsigned long long>(s)
|
||||
* n / num_samples;
|
||||
::new(&(samples[s])) value_type(begin[index]);
|
||||
}
|
||||
for (difference_type s = 0; s < num_samples; ++s)
|
||||
{
|
||||
const unsigned long long index = static_cast<unsigned long long>(s)
|
||||
* n / num_samples;
|
||||
::new(&(samples[s])) value_type(begin[index]);
|
||||
}
|
||||
|
||||
__gnu_sequential::sort(samples, samples + num_samples, comp);
|
||||
__gnu_sequential::sort(samples, samples + num_samples, comp);
|
||||
|
||||
value_type& pivot = samples[pivot_rank * num_samples / n];
|
||||
value_type& pivot = samples[pivot_rank * num_samples / n];
|
||||
|
||||
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
|
||||
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
|
||||
pred(comp, pivot);
|
||||
difference_type split = parallel_partition(begin, end, pred, num_threads);
|
||||
difference_type split = parallel_partition(begin, end, pred, num_threads);
|
||||
|
||||
::operator delete(samples);
|
||||
::operator delete(samples);
|
||||
|
||||
return split;
|
||||
}
|
||||
return split;
|
||||
}
|
||||
|
||||
/** @brief Unbalanced quicksort conquer step.
|
||||
* @param begin Begin iterator of subsequence.
|
||||
|
@ -104,50 +102,51 @@ namespace __gnu_parallel
|
|||
* this part.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename Comparator>
|
||||
inline void
|
||||
parallel_sort_qs_conquer(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Comparator comp,
|
||||
thread_index_t num_threads)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
void
|
||||
parallel_sort_qs_conquer(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Comparator comp,
|
||||
thread_index_t num_threads)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
|
||||
if (num_threads <= 1)
|
||||
{
|
||||
__gnu_sequential::sort(begin, end, comp);
|
||||
return;
|
||||
}
|
||||
if (num_threads <= 1)
|
||||
{
|
||||
__gnu_sequential::sort(begin, end, comp);
|
||||
return;
|
||||
}
|
||||
|
||||
difference_type n = end - begin, pivot_rank;
|
||||
difference_type n = end - begin, pivot_rank;
|
||||
|
||||
if (n <= 1)
|
||||
return;
|
||||
if (n <= 1)
|
||||
return;
|
||||
|
||||
thread_index_t num_threads_left;
|
||||
thread_index_t num_threads_left;
|
||||
|
||||
if ((num_threads % 2) == 1)
|
||||
num_threads_left = num_threads / 2 + 1;
|
||||
else
|
||||
num_threads_left = num_threads / 2;
|
||||
if ((num_threads % 2) == 1)
|
||||
num_threads_left = num_threads / 2 + 1;
|
||||
else
|
||||
num_threads_left = num_threads / 2;
|
||||
|
||||
pivot_rank = n * num_threads_left / num_threads;
|
||||
pivot_rank = n * num_threads_left / num_threads;
|
||||
|
||||
difference_type split = parallel_sort_qs_divide(
|
||||
begin, end, comp, pivot_rank,
|
||||
Settings::sort_qs_num_samples_preset, num_threads);
|
||||
difference_type split =
|
||||
parallel_sort_qs_divide(begin, end, comp, pivot_rank,
|
||||
Settings::sort_qs_num_samples_preset,
|
||||
num_threads);
|
||||
|
||||
#pragma omp parallel sections
|
||||
{
|
||||
{
|
||||
#pragma omp section
|
||||
parallel_sort_qs_conquer(begin, begin + split,
|
||||
comp, num_threads_left);
|
||||
parallel_sort_qs_conquer(begin, begin + split,
|
||||
comp, num_threads_left);
|
||||
#pragma omp section
|
||||
parallel_sort_qs_conquer(begin + split, end,
|
||||
comp, num_threads - num_threads_left);
|
||||
parallel_sort_qs_conquer(begin + split, end,
|
||||
comp, num_threads - num_threads_left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -160,34 +159,33 @@ namespace __gnu_parallel
|
|||
* this part.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename Comparator>
|
||||
inline void
|
||||
parallel_sort_qs(
|
||||
RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Comparator comp,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type n,
|
||||
int num_threads)
|
||||
{
|
||||
_GLIBCXX_CALL(n)
|
||||
void
|
||||
parallel_sort_qs(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Comparator comp, typename std::iterator_traits
|
||||
<RandomAccessIterator>::difference_type n,
|
||||
int num_threads)
|
||||
{
|
||||
_GLIBCXX_CALL(n)
|
||||
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
// At least one element per processor.
|
||||
if (num_threads > n)
|
||||
num_threads = static_cast<thread_index_t>(n);
|
||||
// At least one element per processor.
|
||||
if (num_threads > n)
|
||||
num_threads = static_cast<thread_index_t>(n);
|
||||
|
||||
Settings::sort_qs_num_samples_preset = 100;
|
||||
Settings::sort_qs_num_samples_preset = 100;
|
||||
|
||||
// Hard to avoid.
|
||||
omp_set_num_threads(num_threads);
|
||||
// Hard to avoid.
|
||||
omp_set_num_threads(num_threads);
|
||||
|
||||
parallel_sort_qs_conquer(begin, begin + n, comp, num_threads);
|
||||
}
|
||||
parallel_sort_qs_conquer(begin, begin + n, comp, num_threads);
|
||||
}
|
||||
|
||||
} //namespace __gnu_parallel
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -46,229 +46,288 @@ namespace __gnu_parallel
|
|||
// http://www.math.keio.ac.jp/matumoto/emt.html
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
class mersenne_twister
|
||||
{
|
||||
public:
|
||||
typedef UIntType result_type;
|
||||
static const int word_size = w;
|
||||
static const int state_size = n;
|
||||
static const int shift_size = m;
|
||||
static const int mask_bits = r;
|
||||
static const UIntType parameter_a = a;
|
||||
static const int output_u = u;
|
||||
static const int output_s = s;
|
||||
static const UIntType output_b = b;
|
||||
static const int output_t = t;
|
||||
static const UIntType output_c = c;
|
||||
static const int output_l = l;
|
||||
|
||||
static const bool has_fixed_range = false;
|
||||
|
||||
mersenne_twister() { seed(); }
|
||||
|
||||
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520)
|
||||
// Work around overload resolution problem (Gennadiy E. Rozental)
|
||||
explicit mersenne_twister(const UIntType& value)
|
||||
#else
|
||||
explicit mersenne_twister(UIntType value)
|
||||
#endif
|
||||
{ seed(value); }
|
||||
template<typename It> mersenne_twister(It& first, It last) { seed(first,last); }
|
||||
|
||||
template<typename Generator>
|
||||
explicit mersenne_twister(Generator & gen) { seed(gen); }
|
||||
|
||||
// compiler-generated copy ctor and assignment operator are fine
|
||||
|
||||
void seed() { seed(UIntType(5489)); }
|
||||
|
||||
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520)
|
||||
// Work around overload resolution problem (Gennadiy E. Rozental)
|
||||
void seed(const UIntType& value)
|
||||
#else
|
||||
void seed(UIntType value)
|
||||
#endif
|
||||
class mersenne_twister
|
||||
{
|
||||
// New seeding algorithm from
|
||||
public:
|
||||
typedef UIntType result_type;
|
||||
static const int word_size = w;
|
||||
static const int state_size = n;
|
||||
static const int shift_size = m;
|
||||
static const int mask_bits = r;
|
||||
static const UIntType parameter_a = a;
|
||||
static const int output_u = u;
|
||||
static const int output_s = s;
|
||||
static const UIntType output_b = b;
|
||||
static const int output_t = t;
|
||||
static const UIntType output_c = c;
|
||||
static const int output_l = l;
|
||||
|
||||
static const bool has_fixed_range = false;
|
||||
|
||||
mersenne_twister() { seed(); }
|
||||
|
||||
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520)
|
||||
// Work around overload resolution problem (Gennadiy E. Rozental)
|
||||
explicit
|
||||
mersenne_twister(const UIntType& value)
|
||||
#else
|
||||
explicit
|
||||
mersenne_twister(UIntType value)
|
||||
#endif
|
||||
{ seed(value); }
|
||||
|
||||
template<typename It>
|
||||
mersenne_twister(It& first, It last)
|
||||
{ seed(first,last); }
|
||||
|
||||
template<typename Generator>
|
||||
explicit
|
||||
mersenne_twister(Generator & gen)
|
||||
{ seed(gen); }
|
||||
|
||||
// compiler-generated copy ctor and assignment operator are fine
|
||||
|
||||
void
|
||||
seed()
|
||||
{ seed(UIntType(5489)); }
|
||||
|
||||
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520)
|
||||
// Work around overload resolution problem (Gennadiy E. Rozental)
|
||||
void
|
||||
seed(const UIntType& value)
|
||||
#else
|
||||
void
|
||||
seed(UIntType value)
|
||||
#endif
|
||||
{
|
||||
// New seeding algorithm from
|
||||
// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
|
||||
// In the previous versions, MSBs of the seed affected only MSBs of the
|
||||
// state x[].
|
||||
const UIntType mask = ~0u;
|
||||
x[0] = value & mask;
|
||||
for (i = 1; i < n; i++) {
|
||||
// See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
|
||||
x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
|
||||
// In the previous versions, MSBs of the seed affected only MSBs of the
|
||||
// state x[].
|
||||
const UIntType mask = ~0u;
|
||||
x[0] = value & mask;
|
||||
for (i = 1; i < n; ++i)
|
||||
{
|
||||
// See Knuth "The Art of Computer Programming" Vol. 2,
|
||||
// 3rd ed., page 106
|
||||
x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For GCC, moving this function out-of-line prevents inlining, which may
|
||||
// reduce overall object code size. However, MSVC does not grok
|
||||
// out-of-line definitions of member function templates.
|
||||
template<typename Generator>
|
||||
void seed(Generator & gen)
|
||||
{
|
||||
// I could have used std::generate_n, but it takes "gen" by value
|
||||
for (int j = 0; j < n; j++)
|
||||
x[j] = gen();
|
||||
i = n;
|
||||
}
|
||||
// For GCC, moving this function out-of-line prevents inlining, which may
|
||||
// reduce overall object code size. However, MSVC does not grok
|
||||
// out-of-line definitions of member function templates.
|
||||
template<typename Generator>
|
||||
void
|
||||
seed(Generator & gen)
|
||||
{
|
||||
// I could have used std::generate_n, but it takes "gen" by value
|
||||
for (int j = 0; j < n; ++j)
|
||||
x[j] = gen();
|
||||
i = n;
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
void seed(It& first, It last)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < n && first != last; ++j, ++first)
|
||||
x[j] = *first;
|
||||
i = n;
|
||||
/* if (first == last && j < n)
|
||||
throw std::invalid_argument("mersenne_twister::seed");*/
|
||||
}
|
||||
template<typename It>
|
||||
void
|
||||
seed(It& first, It last)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < n && first != last; ++j, ++first)
|
||||
x[j] = *first;
|
||||
i = n;
|
||||
/* if (first == last && j < n)
|
||||
throw std::invalid_argument("mersenne_twister::seed");*/
|
||||
}
|
||||
|
||||
result_type min() const { return 0; }
|
||||
result_type max() const
|
||||
{
|
||||
// avoid "left shift count >= with of type" warning
|
||||
result_type res = 0;
|
||||
for (int i = 0; i < w; ++i)
|
||||
res |= (1u << i);
|
||||
return res;
|
||||
}
|
||||
result_type
|
||||
min() const
|
||||
{ return 0; }
|
||||
|
||||
result_type
|
||||
max() const
|
||||
{
|
||||
// avoid "left shift count >= with of type" warning
|
||||
result_type res = 0;
|
||||
for (int i = 0; i < w; ++i)
|
||||
res |= (1u << i);
|
||||
return res;
|
||||
}
|
||||
|
||||
result_type operator()();
|
||||
static bool validation(result_type v) { return val == v; }
|
||||
result_type
|
||||
operator()();
|
||||
|
||||
static bool
|
||||
validation(result_type v)
|
||||
{ return val == v; }
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
|
||||
friend bool operator==(const mersenne_twister& x, const mersenne_twister& y)
|
||||
{
|
||||
for (int j = 0; j < state_size; ++j)
|
||||
if (x.compute(j) != y.compute(j))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
friend bool
|
||||
operator==(const mersenne_twister& x, const mersenne_twister& y)
|
||||
{
|
||||
for (int j = 0; j < state_size; ++j)
|
||||
if (x.compute(j) != y.compute(j))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
friend bool operator!=(const mersenne_twister& x, const mersenne_twister& y)
|
||||
{ return !(x == y); }
|
||||
friend bool
|
||||
operator!=(const mersenne_twister& x, const mersenne_twister& y)
|
||||
{ return !(x == y); }
|
||||
#else
|
||||
// Use a member function; Streamable concept not supported.
|
||||
bool operator==(const mersenne_twister& rhs) const
|
||||
{
|
||||
for (int j = 0; j < state_size; ++j)
|
||||
if (compute(j) != rhs.compute(j))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
// Use a member function; Streamable concept not supported.
|
||||
bool
|
||||
operator==(const mersenne_twister& rhs) const
|
||||
{
|
||||
for (int j = 0; j < state_size; ++j)
|
||||
if (compute(j) != rhs.compute(j))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const mersenne_twister& rhs) const
|
||||
{ return !(*this == rhs); }
|
||||
bool
|
||||
operator!=(const mersenne_twister& rhs) const
|
||||
{ return !(*this == rhs); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
// returns x(i-n+index), where index is in 0..n-1
|
||||
UIntType compute(unsigned int index) const
|
||||
{
|
||||
// equivalent to (i-n+index) % 2n, but doesn't produce negative numbers
|
||||
return x[ (i + n + index) % (2*n) ];
|
||||
}
|
||||
void twist(int block);
|
||||
private:
|
||||
// returns x(i-n+index), where index is in 0..n-1
|
||||
UIntType
|
||||
compute(unsigned int index) const
|
||||
{
|
||||
// equivalent to (i-n+index) % 2n, but doesn't produce negative numbers
|
||||
return x[ (i + n + index) % (2*n) ];
|
||||
}
|
||||
|
||||
// state representation: next output is o(x(i))
|
||||
// x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
|
||||
// x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
|
||||
// The goal is to always have x(i-n) ... x(i-1) available for
|
||||
// operator== and save/restore.
|
||||
void
|
||||
twist(int block);
|
||||
|
||||
UIntType x[2*n];
|
||||
int i;
|
||||
// state representation: next output is o(x(i))
|
||||
// x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
|
||||
// x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
|
||||
// The goal is to always have x(i-n) ... x(i-1) available for
|
||||
// operator== and save/restore.
|
||||
|
||||
UIntType x[2*n];
|
||||
int i;
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
||||
// A definition is required even for integral static constants
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const bool mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::has_fixed_range;
|
||||
const bool
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::has_fixed_range;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::state_size;
|
||||
const int
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::state_size;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::shift_size;
|
||||
const int
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::shift_size;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::mask_bits;
|
||||
const int
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::mask_bits;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::parameter_a;
|
||||
const UIntType
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::parameter_a;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_u;
|
||||
const int
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_u;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_s;
|
||||
const int
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_s;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_b;
|
||||
const UIntType
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_b;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_t;
|
||||
const int
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_t;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_c;
|
||||
const UIntType
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_c;
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_l;
|
||||
const int
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_l;
|
||||
#endif
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
void mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::twist(int block)
|
||||
void
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::twist(int block)
|
||||
{
|
||||
const UIntType upper_mask = (~0u) << r;
|
||||
const UIntType lower_mask = ~upper_mask;
|
||||
|
||||
if (block == 0) {
|
||||
for (int j = n; j < 2*n; j++) {
|
||||
UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask);
|
||||
x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
|
||||
if (block == 0)
|
||||
{
|
||||
for (int j = n; j < 2*n; ++j)
|
||||
{
|
||||
UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask);
|
||||
x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
|
||||
}
|
||||
}
|
||||
} else if (block == 1) {
|
||||
// split loop to avoid costly modulo operations
|
||||
{ // extra scope for MSVC brokenness w.r.t. for scope
|
||||
for (int j = 0; j < n-m; j++) {
|
||||
UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
|
||||
x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0);
|
||||
else if (block == 1)
|
||||
{
|
||||
// split loop to avoid costly modulo operations
|
||||
{ // extra scope for MSVC brokenness w.r.t. for scope
|
||||
for (int j = 0; j < n-m; ++j)
|
||||
{
|
||||
UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
|
||||
x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = n-m; j < n-1; ++j)
|
||||
{
|
||||
UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
|
||||
x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
|
||||
}
|
||||
// last iteration
|
||||
UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask);
|
||||
x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0);
|
||||
i = 0;
|
||||
}
|
||||
|
||||
for (int j = n-m; j < n-1; j++) {
|
||||
UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
|
||||
x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
|
||||
}
|
||||
// last iteration
|
||||
UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask);
|
||||
x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
|
||||
int s, UIntType b, int t, UIntType c, int l, UIntType val>
|
||||
inline typename mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::result_type
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::operator()()
|
||||
{
|
||||
if (i == n)
|
||||
twist(0);
|
||||
else if (i >= 2*n)
|
||||
twist(1);
|
||||
// Step 4
|
||||
UIntType z = x[i];
|
||||
++i;
|
||||
z ^= (z >> u);
|
||||
z ^= ((z << s) & b);
|
||||
z ^= ((z << t) & c);
|
||||
z ^= (z >> l);
|
||||
return z;
|
||||
}
|
||||
inline
|
||||
typename mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::result_type
|
||||
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::operator()()
|
||||
{
|
||||
if (i == n)
|
||||
twist(0);
|
||||
else if (i >= 2*n)
|
||||
twist(1);
|
||||
// Step 4
|
||||
UIntType z = x[i];
|
||||
++i;
|
||||
z ^= (z >> u);
|
||||
z ^= ((z << s) & b);
|
||||
z ^= ((z << t) & c);
|
||||
z ^= (z >> l);
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
typedef mersenne_twister<uint32,32,351,175,19,0xccab8ee7,11,
|
||||
|
@ -286,14 +345,15 @@ namespace __gnu_parallel
|
|||
uint64 supremum, RAND_SUP;
|
||||
double supremum_reciprocal, RAND_SUP_REC;
|
||||
|
||||
uint64 cache; /* assumed to be twice as long as the usual random number */
|
||||
int bits_left; /* bit results */
|
||||
uint64 cache; /* assumed to be twice as long as the usual random number */
|
||||
int bits_left; /* bit results */
|
||||
|
||||
static inline uint32 scale_down(uint64 x,
|
||||
static uint32
|
||||
scale_down(uint64 x,
|
||||
#if _GLIBCXX_SCALE_DOWN_FPU
|
||||
uint64 /*supremum*/, double supremum_reciprocal)
|
||||
uint64 /*supremum*/, double supremum_reciprocal)
|
||||
#else
|
||||
uint64 supremum, double /*supremum_reciprocal*/)
|
||||
uint64 supremum, double /*supremum_reciprocal*/)
|
||||
#endif
|
||||
{
|
||||
#if _GLIBCXX_SCALE_DOWN_FPU
|
||||
|
@ -303,82 +363,81 @@ namespace __gnu_parallel
|
|||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
/** @brief Default constructor. Seed with 0. */
|
||||
random_number() :
|
||||
mt(0),
|
||||
supremum(0x100000000ULL),
|
||||
RAND_SUP(1ULL << (sizeof(uint32) * 8)),
|
||||
supremum_reciprocal((double)supremum / (double)RAND_SUP),
|
||||
RAND_SUP_REC(1.0 / (double)RAND_SUP),
|
||||
cache(0), bits_left(0)
|
||||
{
|
||||
}
|
||||
public:
|
||||
/** @brief Default constructor. Seed with 0. */
|
||||
random_number()
|
||||
: mt(0), supremum(0x100000000ULL),
|
||||
RAND_SUP(1ULL << (sizeof(uint32) * 8)),
|
||||
supremum_reciprocal((double)supremum / (double)RAND_SUP),
|
||||
RAND_SUP_REC(1.0 / (double)RAND_SUP),
|
||||
cache(0), bits_left(0) { }
|
||||
|
||||
/** @brief Constructor.
|
||||
* @param seed Random seed.
|
||||
* @param supremum Generate integer random numbers in the interval @c [0,supremum). */
|
||||
random_number(uint32 seed, uint64 supremum = 0x100000000ULL) :
|
||||
mt(seed),
|
||||
supremum(supremum),
|
||||
RAND_SUP(1ULL << (sizeof(uint32) * 8)),
|
||||
supremum_reciprocal((double)supremum / (double)RAND_SUP),
|
||||
RAND_SUP_REC(1.0 / (double)RAND_SUP),
|
||||
cache(0), bits_left(0)
|
||||
{
|
||||
}
|
||||
/** @brief Constructor.
|
||||
* @param seed Random seed.
|
||||
* @param supremum Generate integer random numbers in the
|
||||
* interval @c [0,supremum). */
|
||||
random_number(uint32 seed, uint64 supremum = 0x100000000ULL)
|
||||
: mt(seed), supremum(supremum),
|
||||
RAND_SUP(1ULL << (sizeof(uint32) * 8)),
|
||||
supremum_reciprocal((double)supremum / (double)RAND_SUP),
|
||||
RAND_SUP_REC(1.0 / (double)RAND_SUP),
|
||||
cache(0), bits_left(0) { }
|
||||
|
||||
/** @brief Generate unsigned random 32-bit integer. */
|
||||
inline uint32 operator()()
|
||||
{
|
||||
return scale_down(mt(), supremum, supremum_reciprocal);
|
||||
}
|
||||
/** @brief Generate unsigned random 32-bit integer. */
|
||||
uint32
|
||||
operator()()
|
||||
{ return scale_down(mt(), supremum, supremum_reciprocal); }
|
||||
|
||||
/** @brief Generate unsigned random 32-bit integer in the interval @c [0,local_supremum). */
|
||||
inline uint32 operator()(uint64 local_supremum)
|
||||
{
|
||||
return scale_down(mt(), local_supremum, (double)local_supremum * RAND_SUP_REC);
|
||||
}
|
||||
/** @brief Generate unsigned random 32-bit integer in the
|
||||
interval @c [0,local_supremum). */
|
||||
uint32
|
||||
operator()(uint64 local_supremum)
|
||||
{
|
||||
return scale_down(mt(), local_supremum,
|
||||
(double)local_supremum * RAND_SUP_REC);
|
||||
}
|
||||
|
||||
/** @brief Set the random seed.
|
||||
* @param seed to set. */
|
||||
inline void set_seed(uint32 seed)
|
||||
{
|
||||
mt.seed(seed);
|
||||
cache = mt();
|
||||
bits_left = 32;
|
||||
}
|
||||
/** @brief Set the random seed.
|
||||
* @param seed to set. */
|
||||
void
|
||||
set_seed(uint32 seed)
|
||||
{
|
||||
mt.seed(seed);
|
||||
cache = mt();
|
||||
bits_left = 32;
|
||||
}
|
||||
|
||||
/** @brief Generate a number of random bits, compile-time parameter. */
|
||||
template<int bits>
|
||||
inline unsigned long genrand_bits()
|
||||
{
|
||||
unsigned long res = cache & ((1 << bits) - 1);
|
||||
cache = cache >> bits;
|
||||
bits_left -= bits;
|
||||
if (bits_left < 32)
|
||||
/** @brief Generate a number of random bits, compile-time parameter. */
|
||||
template<int bits>
|
||||
unsigned long
|
||||
genrand_bits()
|
||||
{
|
||||
cache |= (((uint64)mt()) << bits_left);
|
||||
bits_left += 32;
|
||||
unsigned long res = cache & ((1 << bits) - 1);
|
||||
cache = cache >> bits;
|
||||
bits_left -= bits;
|
||||
if (bits_left < 32)
|
||||
{
|
||||
cache |= (((uint64)mt()) << bits_left);
|
||||
bits_left += 32;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Generate a number of random bits, run-time parameter.
|
||||
* @param bits Number of bits to generate. */
|
||||
inline unsigned long genrand_bits(int bits)
|
||||
{
|
||||
unsigned long res = cache & ((1 << bits) - 1);
|
||||
cache = cache >> bits;
|
||||
bits_left -= bits;
|
||||
if (bits_left < 32)
|
||||
{
|
||||
cache |= (((uint64)mt()) << bits_left);
|
||||
bits_left += 32;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Generate a number of random bits, run-time parameter.
|
||||
* @param bits Number of bits to generate. */
|
||||
unsigned long
|
||||
genrand_bits(int bits)
|
||||
{
|
||||
unsigned long res = cache & ((1 << bits) - 1);
|
||||
cache = cache >> bits;
|
||||
bits_left -= bits;
|
||||
if (bits_left < 32)
|
||||
{
|
||||
cache |= (((uint64)mt()) << bits_left);
|
||||
bits_left += 32;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __gnu_parallel
|
||||
|
|
|
@ -124,7 +124,7 @@ template<typename RandomNumberGenerator>
|
|||
/** @brief Random shuffle code executed by each thread.
|
||||
* @param pus Array of thread-local data records. */
|
||||
template<typename RandomAccessIterator, typename RandomNumberGenerator>
|
||||
inline void
|
||||
void
|
||||
parallel_random_shuffle_drs_pu(DRSSorterPU<RandomAccessIterator,
|
||||
RandomNumberGenerator>* pus)
|
||||
{
|
||||
|
@ -213,8 +213,8 @@ template<typename RandomAccessIterator, typename RandomNumberGenerator>
|
|||
thread_index_t target_p = bin_proc[target_bin];
|
||||
|
||||
// Last column [d->num_threads] stays unchanged.
|
||||
::new(&(temporaries[target_p][dist[target_bin + 1]++])) value_type(
|
||||
*(source + i + start));
|
||||
::new(&(temporaries[target_p][dist[target_bin + 1]++]))
|
||||
value_type(*(source + i + start));
|
||||
}
|
||||
|
||||
delete[] oracles;
|
||||
|
@ -260,13 +260,13 @@ template<typename T>
|
|||
* @param rng Random number generator to use.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename RandomNumberGenerator>
|
||||
inline void
|
||||
parallel_random_shuffle_drs(
|
||||
RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type n,
|
||||
thread_index_t num_threads,
|
||||
RandomNumberGenerator& rng)
|
||||
void
|
||||
parallel_random_shuffle_drs(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
typename std::iterator_traits
|
||||
<RandomAccessIterator>::difference_type n,
|
||||
thread_index_t num_threads,
|
||||
RandomNumberGenerator& rng)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
|
@ -393,7 +393,7 @@ template<typename RandomAccessIterator, typename RandomNumberGenerator>
|
|||
* @param rng Random number generator to use.
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename RandomNumberGenerator>
|
||||
inline void
|
||||
void
|
||||
sequential_random_shuffle(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
RandomNumberGenerator& rng)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -81,10 +81,9 @@ template<typename RandomAccessIterator, typename _DifferenceTp>
|
|||
* @param end2 End iterator of second sequence.
|
||||
* @param pred Find predicate.
|
||||
* @return Place of finding in first sequences. */
|
||||
template<
|
||||
typename _RandomAccessIterator1,
|
||||
typename _RandomAccessIterator2,
|
||||
typename Pred>
|
||||
template<typename _RandomAccessIterator1,
|
||||
typename _RandomAccessIterator2,
|
||||
typename Pred>
|
||||
_RandomAccessIterator1
|
||||
search_template(_RandomAccessIterator1 begin1, _RandomAccessIterator1 end1,
|
||||
_RandomAccessIterator2 begin2, _RandomAccessIterator2 end2,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -48,7 +48,7 @@
|
|||
namespace __gnu_parallel
|
||||
{
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
OutputIterator
|
||||
copy_tail(std::pair<InputIterator, InputIterator> b,
|
||||
std::pair<InputIterator, InputIterator> e, OutputIterator r)
|
||||
{
|
||||
|
@ -68,10 +68,9 @@ template<typename InputIterator, typename OutputIterator>
|
|||
return r;
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
struct symmetric_difference_func
|
||||
{
|
||||
typedef std::iterator_traits<InputIterator> traits_type;
|
||||
|
@ -82,9 +81,10 @@ template<
|
|||
|
||||
Comparator comp;
|
||||
|
||||
inline OutputIterator invoke(InputIterator a, InputIterator b,
|
||||
InputIterator c, InputIterator d,
|
||||
OutputIterator r) const
|
||||
OutputIterator
|
||||
invoke(InputIterator a, InputIterator b,
|
||||
InputIterator c, InputIterator d,
|
||||
OutputIterator r) const
|
||||
{
|
||||
while (a != b && c != d)
|
||||
{
|
||||
|
@ -109,9 +109,9 @@ template<
|
|||
return std::copy(c, d, std::copy(a, b, r));
|
||||
}
|
||||
|
||||
inline difference_type
|
||||
count(InputIterator a, InputIterator b, InputIterator c, InputIterator d)
|
||||
const
|
||||
difference_type
|
||||
count(InputIterator a, InputIterator b,
|
||||
InputIterator c, InputIterator d) const
|
||||
{
|
||||
difference_type counter = 0;
|
||||
|
||||
|
@ -137,21 +137,19 @@ template<
|
|||
return counter + (b - a) + (d - c);
|
||||
}
|
||||
|
||||
inline OutputIterator
|
||||
OutputIterator
|
||||
first_empty(InputIterator c, InputIterator d, OutputIterator out) const
|
||||
{ return std::copy(c, d, out); }
|
||||
|
||||
inline OutputIterator
|
||||
OutputIterator
|
||||
second_empty(InputIterator a, InputIterator b, OutputIterator out) const
|
||||
{ return std::copy(a, b, out); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
struct difference_func
|
||||
{
|
||||
typedef std::iterator_traits<InputIterator> traits_type;
|
||||
|
@ -162,7 +160,7 @@ template<
|
|||
|
||||
Comparator comp;
|
||||
|
||||
inline OutputIterator
|
||||
OutputIterator
|
||||
invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d,
|
||||
OutputIterator r) const
|
||||
{
|
||||
|
@ -185,9 +183,9 @@ template<
|
|||
return std::copy(a, b, r);
|
||||
}
|
||||
|
||||
inline difference_type
|
||||
count(InputIterator a, InputIterator b, InputIterator c, InputIterator d)
|
||||
const
|
||||
difference_type
|
||||
count(InputIterator a, InputIterator b,
|
||||
InputIterator c, InputIterator d) const
|
||||
{
|
||||
difference_type counter = 0;
|
||||
|
||||
|
@ -217,10 +215,9 @@ template<
|
|||
};
|
||||
|
||||
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
struct intersection_func
|
||||
{
|
||||
typedef std::iterator_traits<InputIterator> traits_type;
|
||||
|
@ -231,7 +228,7 @@ template<
|
|||
|
||||
Comparator comp;
|
||||
|
||||
inline OutputIterator
|
||||
OutputIterator
|
||||
invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d,
|
||||
OutputIterator r) const
|
||||
{
|
||||
|
@ -253,9 +250,9 @@ template<
|
|||
return r;
|
||||
}
|
||||
|
||||
inline difference_type
|
||||
count(InputIterator a, InputIterator b, InputIterator c, InputIterator d)
|
||||
const
|
||||
difference_type
|
||||
count(InputIterator a, InputIterator b,
|
||||
InputIterator c, InputIterator d) const
|
||||
{
|
||||
difference_type counter = 0;
|
||||
|
||||
|
@ -289,13 +286,13 @@ template<class InputIterator, class OutputIterator, class Comparator>
|
|||
struct union_func
|
||||
{
|
||||
typedef typename std::iterator_traits<InputIterator>::difference_type
|
||||
difference_type;
|
||||
difference_type;
|
||||
|
||||
union_func(Comparator c) : comp(c) {}
|
||||
|
||||
Comparator comp;
|
||||
|
||||
inline OutputIterator
|
||||
OutputIterator
|
||||
invoke(InputIterator a, const InputIterator b, InputIterator c,
|
||||
const InputIterator d, OutputIterator r) const
|
||||
{
|
||||
|
@ -322,9 +319,9 @@ template<class InputIterator, class OutputIterator, class Comparator>
|
|||
return std::copy(c, d, std::copy(a, b, r));
|
||||
}
|
||||
|
||||
inline difference_type
|
||||
count(InputIterator a, InputIterator b, InputIterator c, InputIterator d)
|
||||
const
|
||||
difference_type
|
||||
count(InputIterator a, InputIterator b,
|
||||
InputIterator c, InputIterator d) const
|
||||
{
|
||||
difference_type counter = 0;
|
||||
|
||||
|
@ -356,10 +353,9 @@ template<class InputIterator, class OutputIterator, class Comparator>
|
|||
{ return std::copy(a, b, out); }
|
||||
};
|
||||
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Operation>
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Operation>
|
||||
OutputIterator
|
||||
parallel_set_operation(InputIterator begin1, InputIterator end1,
|
||||
InputIterator begin2, InputIterator end2,
|
||||
|
@ -480,11 +476,10 @@ template<
|
|||
}
|
||||
|
||||
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
OutputIterator
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
inline OutputIterator
|
||||
parallel_set_union(InputIterator begin1, InputIterator end1,
|
||||
InputIterator begin2, InputIterator end2,
|
||||
OutputIterator result, Comparator comp)
|
||||
|
@ -493,11 +488,10 @@ template<
|
|||
union_func< InputIterator, OutputIterator, Comparator>(comp));
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
OutputIterator
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
inline OutputIterator
|
||||
parallel_set_intersection(InputIterator begin1, InputIterator end1,
|
||||
InputIterator begin2, InputIterator end2,
|
||||
OutputIterator result, Comparator comp)
|
||||
|
@ -508,7 +502,7 @@ template<
|
|||
|
||||
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
OutputIterator
|
||||
inline OutputIterator
|
||||
set_intersection(InputIterator begin1, InputIterator end1,
|
||||
InputIterator begin2, InputIterator end2,
|
||||
OutputIterator result)
|
||||
|
@ -517,14 +511,13 @@ template<typename InputIterator, typename OutputIterator>
|
|||
typedef typename traits_type::value_type value_type;
|
||||
|
||||
return set_intersection(begin1, end1, begin2, end2, result,
|
||||
std::less<value_type>());
|
||||
std::less<value_type>());
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
OutputIterator
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
inline OutputIterator
|
||||
parallel_set_difference(InputIterator begin1, InputIterator end1,
|
||||
InputIterator begin2, InputIterator end2,
|
||||
OutputIterator result, Comparator comp)
|
||||
|
@ -533,11 +526,10 @@ template<
|
|||
difference_func<InputIterator, OutputIterator, Comparator>(comp));
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
OutputIterator
|
||||
template<typename InputIterator,
|
||||
typename OutputIterator,
|
||||
typename Comparator>
|
||||
inline OutputIterator
|
||||
parallel_set_symmetric_difference(InputIterator begin1, InputIterator end1,
|
||||
InputIterator begin2, InputIterator end2,
|
||||
OutputIterator result, Comparator comp)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -33,7 +33,8 @@
|
|||
* whether to use parallelized algorithms.
|
||||
* This file is a GNU parallel extension to the Standard C++ Library.
|
||||
*
|
||||
* @section parallelization_decision The decision whether to run an algorithm in parallel.
|
||||
* @section parallelization_decision The decision whether to run
|
||||
* an algorithm in parallel.
|
||||
*
|
||||
* There are several ways the user can switch on and off the
|
||||
* parallel execution of an algorithm, both at compile- and
|
||||
|
@ -104,7 +105,10 @@
|
|||
* __gnu_parallel::Settings::force_parallel, i. e. usually a decision based on
|
||||
* the input size.
|
||||
*/
|
||||
#define _GLIBCXX_PARALLEL_CONDITION(c) (!(__gnu_parallel::Settings::force_sequential) && ((__gnu_parallel::get_max_threads() > 1 && (c)) || __gnu_parallel::Settings::force_parallel))
|
||||
#define _GLIBCXX_PARALLEL_CONDITION(c) \
|
||||
(!(__gnu_parallel::Settings::force_sequential) \
|
||||
&& ((__gnu_parallel::get_max_threads() > 1 \
|
||||
&& (c)) || __gnu_parallel::Settings::force_parallel))
|
||||
|
||||
namespace __gnu_parallel
|
||||
{
|
||||
|
@ -131,7 +135,8 @@ namespace
|
|||
/** @brief Different merging algorithms: bubblesort-alike,
|
||||
loser-tree variants, enum sentinel */
|
||||
enum MultiwayMergeAlgorithm
|
||||
{ BUBBLE, LOSER_TREE_EXPLICIT, LOSER_TREE, LOSER_TREE_COMBINED, LOSER_TREE_SENTINEL, MWM_ALGORITHM_LAST };
|
||||
{ BUBBLE, LOSER_TREE_EXPLICIT, LOSER_TREE, LOSER_TREE_COMBINED,
|
||||
LOSER_TREE_SENTINEL, MWM_ALGORITHM_LAST };
|
||||
|
||||
/** @brief Different splitting strategies for sorting/merging:
|
||||
by sampling, exact */
|
||||
|
@ -340,7 +345,8 @@ namespace
|
|||
volatile sequence_index_t Settings::partition_chunk_size = 1000;
|
||||
volatile double Settings::partition_chunk_share = 0.0;
|
||||
volatile unsigned int Settings::adjacent_difference_minimal_n = 1000;
|
||||
volatile Settings::PartialSumAlgorithm Settings::partial_sum_algorithm = Settings::LINEAR;
|
||||
volatile Settings::PartialSumAlgorithm Settings::
|
||||
partial_sum_algorithm = Settings::LINEAR;
|
||||
volatile unsigned int Settings::partial_sum_minimal_n = 1000;
|
||||
volatile float Settings::partial_sum_dilatation = 1.0f;
|
||||
volatile unsigned int Settings::random_shuffle_minimal_n = 1000;
|
||||
|
@ -352,10 +358,13 @@ namespace
|
|||
|
||||
// unique copy
|
||||
volatile sequence_index_t Settings::unique_copy_minimal_n = 10000;
|
||||
volatile Settings::MultiwayMergeAlgorithm Settings::multiway_merge_algorithm = Settings::LOSER_TREE;
|
||||
volatile Settings::Splitting Settings::multiway_merge_splitting = Settings::EXACT;
|
||||
volatile Settings::MultiwayMergeAlgorithm Settings::
|
||||
multiway_merge_algorithm = Settings::LOSER_TREE;
|
||||
volatile Settings::Splitting Settings::multiway_merge_splitting =
|
||||
Settings::EXACT;
|
||||
volatile unsigned int Settings::multiway_merge_oversampling = 10;
|
||||
volatile Settings::FindDistribution Settings::find_distribution = Settings::CONSTANT_SIZE_BLOCKS;
|
||||
volatile Settings::FindDistribution Settings::find_distribution =
|
||||
Settings::CONSTANT_SIZE_BLOCKS;
|
||||
volatile sequence_index_t Settings::find_sequential_search_size = 256;
|
||||
volatile sequence_index_t Settings::find_initial_block_size = 256;
|
||||
volatile sequence_index_t Settings::find_maximum_block_size = 8192;
|
||||
|
@ -375,7 +384,8 @@ namespace
|
|||
volatile sequence_index_t Settings::set_union_minimal_n = 1000;
|
||||
volatile sequence_index_t Settings::set_intersection_minimal_n = 1000;
|
||||
volatile sequence_index_t Settings::set_difference_minimal_n = 1000;
|
||||
volatile sequence_index_t Settings::set_symmetric_difference_minimal_n = 1000;
|
||||
volatile sequence_index_t Settings::set_symmetric_difference_minimal_n =
|
||||
1000;
|
||||
volatile unsigned long long Settings::L1_cache_size = 16 << 10;
|
||||
volatile unsigned long long Settings::L2_cache_size = 256 << 10;
|
||||
volatile unsigned int Settings::TLB_size = 128;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -69,36 +69,37 @@ namespace __gnu_parallel
|
|||
* @callgraph
|
||||
*/
|
||||
template<typename RandomAccessIterator, typename Comparator>
|
||||
inline void
|
||||
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
|
||||
Comparator comp, bool stable)
|
||||
{
|
||||
_GLIBCXX_CALL(end - begin)
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
inline void
|
||||
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
|
||||
Comparator comp, bool stable)
|
||||
{
|
||||
_GLIBCXX_CALL(end - begin)
|
||||
typedef std::iterator_traits<RandomAccessIterator> traits_type;
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
|
||||
if (begin != end)
|
||||
{
|
||||
difference_type n = end - begin;
|
||||
if (begin != end)
|
||||
{
|
||||
difference_type n = end - begin;
|
||||
|
||||
if (false) ;
|
||||
if (false) ;
|
||||
#if _GLIBCXX_MERGESORT
|
||||
else if (Settings::sort_algorithm == Settings::MWMS || stable)
|
||||
parallel_sort_mwms(begin, end, comp, n, get_max_threads(), stable);
|
||||
else if (Settings::sort_algorithm == Settings::MWMS || stable)
|
||||
parallel_sort_mwms(begin, end, comp, n, get_max_threads(), stable);
|
||||
#endif
|
||||
#if _GLIBCXX_QUICKSORT
|
||||
else if (Settings::sort_algorithm == Settings::QS && !stable)
|
||||
parallel_sort_qs(begin, end, comp, n, get_max_threads());
|
||||
else if (Settings::sort_algorithm == Settings::QS && !stable)
|
||||
parallel_sort_qs(begin, end, comp, n, get_max_threads());
|
||||
#endif
|
||||
#if _GLIBCXX_BAL_QUICKSORT
|
||||
else if (Settings::sort_algorithm == Settings::QS_BALANCED && !stable)
|
||||
parallel_sort_qsb(begin, end, comp, n, get_max_threads());
|
||||
else if (Settings::sort_algorithm == Settings::QS_BALANCED
|
||||
&& !stable)
|
||||
parallel_sort_qsb(begin, end, comp, n, get_max_threads());
|
||||
#endif
|
||||
else
|
||||
__gnu_sequential::sort(begin, end, comp);
|
||||
}
|
||||
}
|
||||
else
|
||||
__gnu_sequential::sort(begin, end, comp);
|
||||
}
|
||||
}
|
||||
} // end namespace __gnu_parallel
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -50,11 +50,10 @@ namespace __gnu_parallel
|
|||
* @param result Begin iterator of result sequence.
|
||||
* @param binary_pred Equality predicate.
|
||||
* @return End iterator of result sequence. */
|
||||
template<
|
||||
typename InputIterator,
|
||||
class OutputIterator,
|
||||
class BinaryPredicate>
|
||||
inline OutputIterator
|
||||
template<typename InputIterator,
|
||||
class OutputIterator,
|
||||
class BinaryPredicate>
|
||||
OutputIterator
|
||||
parallel_unique_copy(InputIterator first, InputIterator last,
|
||||
OutputIterator result, BinaryPredicate binary_pred)
|
||||
{
|
||||
|
@ -79,10 +78,10 @@ template<
|
|||
{
|
||||
# pragma omp single
|
||||
{
|
||||
num_threads = omp_get_num_threads();
|
||||
borders = new difference_type[num_threads + 2];
|
||||
equally_split(size, num_threads + 1, borders);
|
||||
counter = new difference_type[num_threads + 1];
|
||||
num_threads = omp_get_num_threads();
|
||||
borders = new difference_type[num_threads + 2];
|
||||
equally_split(size, num_threads + 1, borders);
|
||||
counter = new difference_type[num_threads + 1];
|
||||
}
|
||||
|
||||
thread_index_t iam = omp_get_thread_num();
|
||||
|
@ -99,14 +98,14 @@ template<
|
|||
begin = borders[0] + 1; // == 1
|
||||
end = borders[iam + 1];
|
||||
|
||||
i++;
|
||||
++i;
|
||||
*out++ = *first;
|
||||
|
||||
for (InputIterator iter = first + begin; iter < first + end; ++iter)
|
||||
{
|
||||
if (!binary_pred(*iter, *(iter-1)))
|
||||
{
|
||||
i++;
|
||||
++i;
|
||||
*out++ = *iter;
|
||||
}
|
||||
}
|
||||
|
@ -118,11 +117,9 @@ template<
|
|||
|
||||
for (InputIterator iter = first + begin; iter < first + end; ++iter)
|
||||
{
|
||||
if (!binary_pred(*iter, *(iter-1)))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!binary_pred(*iter, *(iter - 1)))
|
||||
++i;
|
||||
}
|
||||
}
|
||||
counter[iam] = i;
|
||||
|
||||
|
@ -136,7 +133,7 @@ template<
|
|||
|
||||
if (iam == 0)
|
||||
{
|
||||
for (int t = 0; t < num_threads; t++)
|
||||
for (int t = 0; t < num_threads; ++t)
|
||||
begin_output += counter[t];
|
||||
|
||||
i = 0;
|
||||
|
@ -148,9 +145,9 @@ template<
|
|||
|
||||
for (InputIterator iter = first + begin; iter < first + end; ++iter)
|
||||
{
|
||||
if (iter == first || !binary_pred(*iter, *(iter-1)))
|
||||
if (iter == first || !binary_pred(*iter, *(iter - 1)))
|
||||
{
|
||||
i++;
|
||||
++i;
|
||||
*iter_out++ = *iter;
|
||||
}
|
||||
}
|
||||
|
@ -166,10 +163,8 @@ template<
|
|||
for (InputIterator iter = first + begin; iter < first + end; ++iter)
|
||||
{
|
||||
if (!binary_pred(*iter, *(iter-1)))
|
||||
{
|
||||
*iter_out++ = *iter;
|
||||
}
|
||||
}
|
||||
*iter_out++ = *iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,8 +188,8 @@ template<typename InputIterator, class OutputIterator>
|
|||
OutputIterator result)
|
||||
{
|
||||
typedef typename std::iterator_traits<InputIterator>::value_type value_type;
|
||||
|
||||
return parallel_unique_copy(first, last, result, std::equal_to<value_type>());
|
||||
return parallel_unique_copy(first, last, result,
|
||||
std::equal_to<value_type>());
|
||||
}
|
||||
|
||||
}//namespace __gnu_parallel
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
|
@ -96,20 +96,19 @@ template<typename _DifferenceTp>
|
|||
* std::count_n()).
|
||||
* @return User-supplied functor (that may contain a part of the result).
|
||||
*/
|
||||
template<
|
||||
typename RandomAccessIterator,
|
||||
typename Op,
|
||||
typename Fu,
|
||||
typename Red,
|
||||
typename Result>
|
||||
template<typename RandomAccessIterator,
|
||||
typename Op,
|
||||
typename Fu,
|
||||
typename Red,
|
||||
typename Result>
|
||||
Op
|
||||
for_each_template_random_access_workstealing(
|
||||
RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Op op, Fu& f, Red r,
|
||||
Result base, Result& output,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
bound)
|
||||
for_each_template_random_access_workstealing(RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
Op op, Fu& f, Red r,
|
||||
Result base, Result& output,
|
||||
typename std::iterator_traits
|
||||
<RandomAccessIterator>::
|
||||
difference_type bound)
|
||||
{
|
||||
_GLIBCXX_CALL(end - begin)
|
||||
|
||||
|
@ -180,7 +179,7 @@ template<
|
|||
|
||||
// This thread is currently working.
|
||||
# pragma omp atomic
|
||||
busy++;
|
||||
++busy;
|
||||
|
||||
iam_working = true;
|
||||
|
||||
|
@ -198,8 +197,8 @@ template<
|
|||
// Cannot use volatile variable directly.
|
||||
difference_type my_first = my_job.first;
|
||||
result = f(op, begin + my_first);
|
||||
my_job.first++;
|
||||
my_job.load--;
|
||||
++my_job.first;
|
||||
--my_job.load;
|
||||
}
|
||||
|
||||
RandomAccessIterator current;
|
||||
|
@ -226,11 +225,11 @@ template<
|
|||
my_job.load = my_job.last - my_job.first + 1;
|
||||
for (difference_type job_counter = 0;
|
||||
job_counter < chunk_size && current_job <= my_job.last;
|
||||
job_counter++)
|
||||
++job_counter)
|
||||
{
|
||||
// Yes: process it!
|
||||
current = begin + current_job;
|
||||
current_job++;
|
||||
++current_job;
|
||||
|
||||
// Do actual work.
|
||||
result = r(result, f(op, current));
|
||||
|
@ -244,7 +243,7 @@ template<
|
|||
{
|
||||
// This thread no longer has work.
|
||||
# pragma omp atomic
|
||||
busy--;
|
||||
--busy;
|
||||
|
||||
iam_working = false;
|
||||
}
|
||||
|
@ -286,7 +285,7 @@ template<
|
|||
|
||||
// Has potential work again.
|
||||
# pragma omp atomic
|
||||
busy++;
|
||||
++busy;
|
||||
iam_working = true;
|
||||
|
||||
# pragma omp flush(busy)
|
||||
|
|
Loading…
Add table
Reference in a new issue