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:
Paolo Carlini 2008-01-10 02:07:41 +00:00 committed by Paolo Carlini
parent 299f57348c
commit 5817ff8e5f
32 changed files with 3871 additions and 3356 deletions

View file

@ -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.

View file

@ -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>

View file

@ -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

View file

@ -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;
}

View file

@ -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)
{

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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];
}

View file

@ -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.

View file

@ -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)
{

View file

@ -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,

View file

@ -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());
}
}

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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,

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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)