aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@montsouris.artheist.org>2007-10-09 20:48:38 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2007-10-09 20:48:38 +0000
commitdfbed397860edaeb0116956cc3cdf9d9f60cff3d (patch)
tree8f68ccf134a3987bca19b620318ed934b74ac3ab
parentafd428f812ea77aac8574629bdc1e779c7d050d4 (diff)
downloadgcc-dfbed397860edaeb0116956cc3cdf9d9f60cff3d.zip
gcc-dfbed397860edaeb0116956cc3cdf9d9f60cff3d.tar.gz
gcc-dfbed397860edaeb0116956cc3cdf9d9f60cff3d.tar.bz2
PR libstdc++/33489 continued.
2007-10-09 Benjamin Kosnik <bkoz@montsouris.artheist.org> PR libstdc++/33489 continued. * include/parallel/features.h (_GLIBCXX_LOSER_TREE): Set to zero. (_GLIBCXX_LOSER_TREE_POINTER): Set to one. (_GLIBCXX_LOSER_TREE_UNGUARDED): Set to zero. (_GLIBCXX_LOSER_TREE_POINTER_UNGUARDED): Set to one. * include/parallel/multiway_merge.h (parallel_multiway_merge): Change array of value_type to array of value_type pointers. (multiway_merge_bubble): Same. (multiway_merge_loser_tree): Same. * include/parallel/merge.h (merge_advance_movc): Change to avoid default construction. * include/parallel/multiseq_selection.h (multiseq_partition): Replace value_type, bool pair with value_type*, null-initialized. * include/parallel/multiway_mergesort.h (parallel_sort_mwms): Don't use array form of operator new for value_types. (parallel_sort_mwms_pu): Same. * include/parallel/quicksort.h (parallel_sort_qs_divide): Don't use array form to construct pointer to value_type on stack, instead use __builtin_alloca. * include/parallel/random_shuffle.h (sequential_random_shuffle): Same, but use operator new. (parallel_random_shuffle_drs_pu): Same. * include/parallel/partial_sum.h ( parallel_partial_sum_linear): Same. * include/parallel/losertree.h: Format. * include/parallel/settings.h: Format. * include/parallel/multiway_merge.h: Move traits to.... * include/parallel/losertree.h: ... here. From-SVN: r129179
-rw-r--r--libstdc++-v3/ChangeLog32
-rw-r--r--libstdc++-v3/include/parallel/features.h8
-rw-r--r--libstdc++-v3/include/parallel/losertree.h51
-rw-r--r--libstdc++-v3/include/parallel/merge.h13
-rw-r--r--libstdc++-v3/include/parallel/multiseq_selection.h41
-rw-r--r--libstdc++-v3/include/parallel/multiway_merge.h85
-rw-r--r--libstdc++-v3/include/parallel/multiway_mergesort.h27
-rw-r--r--libstdc++-v3/include/parallel/partial_sum.h2
-rw-r--r--libstdc++-v3/include/parallel/quicksort.h8
-rw-r--r--libstdc++-v3/include/parallel/random_shuffle.h4
-rw-r--r--libstdc++-v3/include/parallel/settings.h2
11 files changed, 147 insertions, 126 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index f09d71e..f851d39 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,35 @@
+2007-10-09 Benjamin Kosnik <bkoz@montsouris.artheist.org>
+
+ PR libstdc++/33489 continued.
+ * include/parallel/features.h (_GLIBCXX_LOSER_TREE): Set to zero.
+ (_GLIBCXX_LOSER_TREE_POINTER): Set to one.
+ (_GLIBCXX_LOSER_TREE_UNGUARDED): Set to zero.
+ (_GLIBCXX_LOSER_TREE_POINTER_UNGUARDED): Set to one.
+ * include/parallel/multiway_merge.h (parallel_multiway_merge):
+ Change array of value_type to array of value_type pointers.
+ (multiway_merge_bubble): Same.
+ (multiway_merge_loser_tree): Same.
+ * include/parallel/merge.h (merge_advance_movc): Change to avoid
+ default construction.
+ * include/parallel/multiseq_selection.h (multiseq_partition):
+ Replace value_type, bool pair with value_type*, null-initialized.
+ * include/parallel/multiway_mergesort.h (parallel_sort_mwms):
+ Don't use array form of operator new for value_types.
+ (parallel_sort_mwms_pu): Same.
+ * include/parallel/quicksort.h (parallel_sort_qs_divide): Don't
+ use array form to construct pointer to value_type on stack,
+ instead use __builtin_alloca.
+ * include/parallel/random_shuffle.h (sequential_random_shuffle): Same,
+ but use operator new.
+ (parallel_random_shuffle_drs_pu): Same.
+ * include/parallel/partial_sum.h ( parallel_partial_sum_linear): Same.
+
+ * include/parallel/losertree.h: Format.
+ * include/parallel/settings.h: Format.
+
+ * include/parallel/multiway_merge.h: Move traits to....
+ * include/parallel/losertree.h: ... here.
+
2007-10-09 Paolo Carlini <pcarlini@suse.de>
* include/tr1_impl/type_traitsfwd.h (add_reference): Remove.
diff --git a/libstdc++-v3/include/parallel/features.h b/libstdc++-v3/include/parallel/features.h
index 8377148..c67ffb5 100644
--- a/libstdc++-v3/include/parallel/features.h
+++ b/libstdc++-v3/include/parallel/features.h
@@ -66,7 +66,7 @@
* @brief Include guarded (sequences may run empty) loser tree,
* moving objects.
* @see __gnu_parallel::Settings multiway_merge_algorithm */
-#define _GLIBCXX_LOSER_TREE 1
+#define _GLIBCXX_LOSER_TREE 0
#endif
#ifndef _GLIBCXX_LOSER_TREE_EXPLICIT
@@ -88,7 +88,7 @@
/** @def _GLIBCXX_LOSER_TREE_POINTER
* @brief Include some loser tree variant.
* @see __gnu_parallel::Settings multiway_merge_algorithm */
-#define _GLIBCXX_LOSER_TREE_POINTER 0
+#define _GLIBCXX_LOSER_TREE_POINTER 1
#endif
#ifndef _GLIBCXX_LOSER_TREE_UNGUARDED
@@ -96,14 +96,14 @@
* @brief Include unguarded (sequences must not run empty) loser
* tree, moving objects.
* @see __gnu_parallel::Settings multiway_merge_algorithm */
-#define _GLIBCXX_LOSER_TREE_UNGUARDED 1
+#define _GLIBCXX_LOSER_TREE_UNGUARDED 0
#endif
#ifndef _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED
/** @def _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED
* @brief Include some loser tree variant.
* @see __gnu_parallel::Settings multiway_merge_algorithm */
-#define _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED 0
+#define _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED 1
#endif
#ifndef _GLIBCXX_LOSER_TREE_COMBINED
diff --git a/libstdc++-v3/include/parallel/losertree.h b/libstdc++-v3/include/parallel/losertree.h
index 1823282..8117995 100644
--- a/libstdc++-v3/include/parallel/losertree.h
+++ b/libstdc++-v3/include/parallel/losertree.h
@@ -36,7 +36,7 @@
// Written by Johannes Singler.
#ifndef _GLIBCXX_PARALLEL_LOSERTREE_H
-#define _GLIBCXX_PARALLEL_LOSERTREE_H
+#define _GLIBCXX_PARALLEL_LOSERTREE_H 1
#include <functional>
@@ -133,7 +133,8 @@ namespace __gnu_parallel
for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
{
// The smaller one gets promoted.
- if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup && comp(losers[pos].key, key))
+ if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
+ && comp(losers[pos].key, key))
|| losers[pos].inf || sup)
{
// The other one is smaller.
@@ -251,7 +252,8 @@ namespace __gnu_parallel
print()
{
for (unsigned int i = 0; i < (k * 2); i++)
- printf("%d %d from %d, %d\n", i, losers[i].key, losers[i].source, losers[i].sup);
+ printf("%d %d from %d, %d\n", i, losers[i].key,
+ losers[i].source, losers[i].sup);
}
inline int
@@ -682,7 +684,8 @@ namespace __gnu_parallel
init()
{ losers[0] = losers[init_winner(1)]; }
- inline void delete_min_insert(const T& key, bool sup)
+ inline void
+ delete_min_insert(const T& key, bool sup)
{
const T* keyp = &key;
int source = losers[0].source;
@@ -708,7 +711,7 @@ namespace __gnu_parallel
{ return insert_start(key, source, sup); }
unsigned int
- init_winner_stable (unsigned int root)
+ init_winner_stable(unsigned int root)
{
if (root >= k)
{
@@ -719,7 +722,8 @@ namespace __gnu_parallel
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].keyp, *losers[left].keyp)))
+ || (!losers[left].sup && !comp(*losers[right].keyp,
+ *losers[left].keyp)))
{
// Left one is less or equal.
losers[root] = losers[right];
@@ -749,7 +753,8 @@ namespace __gnu_parallel
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))))
+ (!comp(*keyp, *losers[pos].keyp)
+ && losers[pos].source < source))))
{
// The other one is smaller.
std::swap(losers[pos].sup, sup);
@@ -1061,7 +1066,8 @@ namespace __gnu_parallel
{
// The smaller one gets promoted, ties are broken by source.
if (comp(*losers[pos].keyp, *keyp)
- || (!comp(*keyp, *losers[pos].keyp) && losers[pos].source < source))
+ || (!comp(*keyp, *losers[pos].keyp)
+ && losers[pos].source < source))
{
// The other one is smaller.
std::swap(losers[pos].source, source);
@@ -1072,6 +1078,35 @@ namespace __gnu_parallel
}
};
#endif
+
+ template<typename _ValueTp, class Comparator>
+ struct loser_tree_traits
+ {
+#if _GLIBCXX_LOSER_TREE
+ typedef LoserTree<_ValueTp, Comparator> LT;
+#else
+# if _GLIBCXX_LOSER_TREE_POINTER
+ typedef LoserTreePointer<_ValueTp, Comparator> LT;
+# else
+# error Must define some type in losertree.h.
+# endif
+#endif
+ };
+
+ template<typename _ValueTp, class Comparator>
+ struct loser_tree_traits_unguarded
+ {
+#if _GLIBCXX_LOSER_TREE_UNGUARDED
+ typedef LoserTreeUnguarded<_ValueTp, Comparator> LT;
+#else
+# if _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED
+ typedef LoserTreePointerUnguarded<_ValueTp, Comparator> LT;
+# else
+# error Must define some type in losertree.h.
+# endif
+#endif
+ };
+
}
#endif
diff --git a/libstdc++-v3/include/parallel/merge.h b/libstdc++-v3/include/parallel/merge.h
index 0bf2949..bbac9b9 100644
--- a/libstdc++-v3/include/parallel/merge.h
+++ b/libstdc++-v3/include/parallel/merge.h
@@ -113,15 +113,10 @@ namespace __gnu_parallel
while (begin1 != end1 && begin2 != end2 && max_length > 0)
{
- value_type1 element1;
- value_type2 element2;
- RandomAccessIterator1 next1;
- RandomAccessIterator2 next2;
-
- next1 = begin1 + 1;
- next2 = begin2 + 1;
- element1 = *begin1;
- element2 = *begin2;
+ RandomAccessIterator1 next1 = begin1 + 1;
+ RandomAccessIterator2 next2 = begin2 + 1;
+ value_type1 element1 = *begin1;
+ value_type2 element2 = *begin2;
if (comp(element2, element1))
{
diff --git a/libstdc++-v3/include/parallel/multiseq_selection.h b/libstdc++-v3/include/parallel/multiseq_selection.h
index 208f409..10f4c73 100644
--- a/libstdc++-v3/include/parallel/multiseq_selection.h
+++ b/libstdc++-v3/include/parallel/multiseq_selection.h
@@ -132,10 +132,10 @@ namespace __gnu_parallel
typedef typename std::iterator_traits<RanSeqs>::value_type::first_type It;
typedef typename std::iterator_traits<It>::difference_type difference_type;
- typedef typename std::iterator_traits<It>::value_type T;
+ typedef typename std::iterator_traits<It>::value_type value_type;
- lexicographic<T, int, Comparator> lcomp(comp);
- lexicographic_reverse<T, int, Comparator> lrcomp(comp);
+ lexicographic<value_type, int, Comparator> lcomp(comp);
+ lexicographic_reverse<value_type, int, Comparator> lrcomp(comp);
// Number of sequences, number of elements in total (possibly
// including padding).
@@ -188,7 +188,7 @@ namespace __gnu_parallel
#define S(i) (begin_seqs[i].first)
// Initial partition.
- std::vector<std::pair<T, int> > sample;
+ std::vector<std::pair<value_type, int> > sample;
for (int i = 0; i < m; i++)
if (n < ns[i]) //sequence long enough
@@ -213,7 +213,7 @@ namespace __gnu_parallel
n /= 2;
int lmax_seq = -1; // to avoid warning
- const T* lmax = NULL; // impossible to avoid the warning?
+ const value_type* lmax = NULL; // impossible to avoid the warning?
for (int i = 0; i < m; i++)
{
if (a[i] > 0)
@@ -258,7 +258,7 @@ namespace __gnu_parallel
if (skew > 0)
{
// Move to the left, find smallest.
- std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int> >, lexicographic_reverse<T, int, Comparator> > pq(lrcomp);
+ std::priority_queue<std::pair<value_type, int>, std::vector<std::pair<value_type, int> >, lexicographic_reverse<value_type, int, Comparator> > pq(lrcomp);
for (int i = 0; i < m; i++)
if (b[i] < ns[i])
@@ -279,7 +279,7 @@ namespace __gnu_parallel
else if (skew < 0)
{
// Move to the right, find greatest.
- std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int> >, lexicographic<T, int, Comparator> > pq(lcomp);
+ std::priority_queue<std::pair<value_type, int>, std::vector<std::pair<value_type, int> >, lexicographic<value_type, int, Comparator> > pq(lcomp);
for (int i = 0; i < m; i++)
if (a[i] > 0)
@@ -308,36 +308,30 @@ namespace __gnu_parallel
// Compare the keys on both edges of the border.
// Maximum of left edge, minimum of right edge.
- bool maxleftset = false, minrightset = false;
- T maxleft, minright; // Impossible to avoid the warning?
+ value_type* maxleft = NULL;
+ value_type* minright = NULL;
for (int i = 0; i < m; i++)
{
if (a[i] > 0)
{
- if (!maxleftset)
- {
- maxleft = S(i)[a[i] - 1];
- maxleftset = true;
- }
+ if (!maxleft)
+ maxleft = &(S(i)[a[i] - 1]);
else
{
// Max, favor rear sequences.
- if (!comp(S(i)[a[i] - 1], maxleft))
- maxleft = S(i)[a[i] - 1];
+ if (!comp(S(i)[a[i] - 1], *maxleft))
+ maxleft = &(S(i)[a[i] - 1]);
}
}
if (b[i] < ns[i])
{
- if (!minrightset)
- {
- minright = S(i)[b[i]];
- minrightset = true;
- }
+ if (!minright)
+ minright = &(S(i)[b[i]]);
else
{
// Min, favor fore sequences.
- if (comp(S(i)[b[i]], minright))
- minright = S(i)[b[i]];
+ if (comp(S(i)[b[i]], *minright))
+ minright = &(S(i)[b[i]]);
}
}
}
@@ -352,7 +346,6 @@ namespace __gnu_parallel
}
-
/**
* @brief Selects the element at a certain global rank from several
* sorted sequences.
diff --git a/libstdc++-v3/include/parallel/multiway_merge.h b/libstdc++-v3/include/parallel/multiway_merge.h
index c940e45..b723215 100644
--- a/libstdc++-v3/include/parallel/multiway_merge.h
+++ b/libstdc++-v3/include/parallel/multiway_merge.h
@@ -265,7 +265,7 @@ namespace __gnu_parallel
{
_GLIBCXX_CALL(seqs_end - seqs_begin)
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>::value_type::first_type
+ typedef typename std::iterator_traits<RandomAccessIteratorIterator>::value_type::first_type
RandomAccessIterator1;
typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
value_type;
@@ -346,8 +346,7 @@ namespace __gnu_parallel
difference_type;
// Last element in sequence.
- value_type max;
- bool max_found = false;
+ value_type* max = NULL;
for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; s++)
{
if ((*s).first == (*s).second)
@@ -357,20 +356,19 @@ namespace __gnu_parallel
value_type& v = *((*s).second - 1);
// Strictly greater.
- if (!max_found || comp(max, v))
- max = v;
- max_found = true;
+ if (!max || comp(*max, v))
+ max = &v;
}
difference_type overhang_size = 0;
-
for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; s++)
{
- RandomAccessIterator1 split = std::lower_bound((*s).first, (*s).second, max, comp);
+ RandomAccessIterator1 split = std::lower_bound((*s).first, (*s).second,
+ *max, comp);
overhang_size += (*s).second - split;
// Set sentinel.
- *((*s).second) = max;
+ *((*s).second) = *max;
}
// So many elements will be left over afterwards.
@@ -722,7 +720,7 @@ namespace __gnu_parallel
// Num remaining pieces.
int k = static_cast<int>(seqs_end - seqs_begin), nrp;
- value_type* pl = new value_type[k];
+ value_type* pl = static_cast<value_type*>(::operator new(sizeof(value_type) * k));
int* source = new int[k];
difference_type total_length = 0;
@@ -890,7 +888,7 @@ namespace __gnu_parallel
{
_GLIBCXX_CALL(length)
- typedef _DifferenceTp difference_type;
+ typedef _DifferenceTp difference_type;
typedef typename std::iterator_traits<RandomAccessIteratorIterator>::value_type::first_type
RandomAccessIterator1;
typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
@@ -902,19 +900,21 @@ namespace __gnu_parallel
difference_type total_length = 0;
+ // Default value for potentially non-default-constructible types.
+ value_type* defaultcons = NULL;
for (int t = 0; t < k; t++)
{
if (stable)
{
if (seqs_begin[t].first == seqs_begin[t].second)
- lt.insert_start_stable(value_type(), t, true);
+ lt.insert_start_stable(*defaultcons, t, true);
else
lt.insert_start_stable(*seqs_begin[t].first, t, false);
}
else
{
if (seqs_begin[t].first == seqs_begin[t].second)
- lt.insert_start(value_type(), t, true);
+ lt.insert_start(*defaultcons, t, true);
else
lt.insert_start(*seqs_begin[t].first, t, false);
}
@@ -942,7 +942,7 @@ namespace __gnu_parallel
// Feed.
if (seqs_begin[source].first == seqs_begin[source].second)
- lt.delete_min_insert_stable(value_type(), true);
+ lt.delete_min_insert_stable(*defaultcons, true);
else
// Replace from same source.
lt.delete_min_insert_stable(*seqs_begin[source].first, false);
@@ -960,7 +960,7 @@ namespace __gnu_parallel
// Feed.
if (seqs_begin[source].first == seqs_begin[source].second)
- lt.delete_min_insert(value_type(), true);
+ lt.delete_min_insert(*defaultcons, true);
else
// Replace from same source.
lt.delete_min_insert(*seqs_begin[source].first, false);
@@ -1083,59 +1083,6 @@ namespace __gnu_parallel
return target;
}
- template<typename _ValueTp, class Comparator>
- struct loser_tree_traits
- {
- typedef LoserTree/*Pointer*/<_ValueTp, Comparator> LT;
- };
-
-
- /*#define NO_POINTER(T) \
- template<typename Comparator> \
- struct loser_tree_traits<T, Comparator> \
- { \
- typedef LoserTreePointer<T, Comparator> LT; \
- };*/
- //
- // NO_POINTER(unsigned char)
- // NO_POINTER(char)
- // NO_POINTER(unsigned short)
- // NO_POINTER(short)
- // NO_POINTER(unsigned int)
- // NO_POINTER(int)
- // NO_POINTER(unsigned long)
- // NO_POINTER(long)
- // NO_POINTER(unsigned long long)
- // NO_POINTER(long long)
- //
- // #undef NO_POINTER
-
- template<typename _ValueTp, class Comparator>
- struct loser_tree_traits_unguarded
- {
- typedef LoserTreeUnguarded<_ValueTp, Comparator> LT;
- };
-
- /*#define NO_POINTER_UNGUARDED(T) \
- template<typename Comparator> \
- struct loser_tree_traits_unguarded<T, Comparator> \
- { \
- typedef LoserTreePointerUnguarded<T, Comparator> LT; \
- };*/
- //
- // NO_POINTER_UNGUARDED(unsigned char)
- // NO_POINTER_UNGUARDED(char)
- // NO_POINTER_UNGUARDED(unsigned short)
- // NO_POINTER_UNGUARDED(short)
- // NO_POINTER_UNGUARDED(unsigned int)
- // NO_POINTER_UNGUARDED(int)
- // NO_POINTER_UNGUARDED(unsigned long)
- // NO_POINTER_UNGUARDED(long)
- // NO_POINTER_UNGUARDED(unsigned long long)
- // NO_POINTER_UNGUARDED(long long)
- //
- // #undef NO_POINTER_UNGUARDED
-
template<typename RandomAccessIteratorIterator, typename RandomAccessIterator3, typename _DifferenceTp, typename Comparator>
RandomAccessIterator3
multiway_merge_loser_tree_combined(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, Comparator comp, _DifferenceTp length, bool stable)
@@ -1423,7 +1370,7 @@ namespace __gnu_parallel
if (Settings::multiway_merge_splitting == Settings::SAMPLING)
{
- value_type* samples = new value_type[k * num_samples];
+ value_type* samples = static_cast<value_type*>(::operator new(sizeof(value_type) * k * num_samples));
// Sample.
for (int s = 0; s < k; s++)
for (int i = 0; (difference_type)i < num_samples; i++)
diff --git a/libstdc++-v3/include/parallel/multiway_mergesort.h b/libstdc++-v3/include/parallel/multiway_mergesort.h
index 7f0f3c0..9cc0405 100644
--- a/libstdc++-v3/include/parallel/multiway_mergesort.h
+++ b/libstdc++-v3/include/parallel/multiway_mergesort.h
@@ -160,7 +160,6 @@ namespace __gnu_parallel
typedef typename traits_type::difference_type difference_type;
Timing<sequential_tag> t;
-
t.tic();
PMWMSSortingData<RandomAccessIterator>* sd = d->sd;
@@ -178,7 +177,7 @@ namespace __gnu_parallel
typedef value_type* SortingPlacesIterator;
// Sort in temporary storage, leave space for sentinel.
- sd->sorting_places[iam] = sd->temporaries[iam] = static_cast<value_type*>(::operator new(sizeof(value_type) *(length_local + 1)));
+ sd->sorting_places[iam] = sd->temporaries[iam] = static_cast<value_type*>(::operator new(sizeof(value_type) * (length_local + 1)));
// Copy there.
std::uninitialized_copy(sd->source + sd->starts[iam], sd->source + sd->starts[iam] + length_local, sd->sorting_places[iam]);
@@ -208,7 +207,9 @@ namespace __gnu_parallel
t.tic("sample/wait");
#pragma omp single
- __gnu_sequential::sort(sd->samples, sd->samples + (num_samples * d->num_threads), comp);
+ __gnu_sequential::sort(sd->samples,
+ sd->samples + (num_samples * d->num_threads),
+ comp);
#pragma omp barrier
@@ -288,7 +289,7 @@ namespace __gnu_parallel
// Merge to temporary storage, uninitialized creation not possible
// since there is no multiway_merge calling the placement new
// instead of the assignment operator.
- sd->merging_places[iam] = sd->temporaries[iam] = new value_type[length_am];
+ sd->merging_places[iam] = sd->temporaries[iam] = static_cast<value_type*>(::operator new(sizeof(value_type) * length_am));
#else
// Merge directly to target.
sd->merging_places[iam] = sd->source + offset;
@@ -337,7 +338,10 @@ namespace __gnu_parallel
*/
template<typename RandomAccessIterator, typename Comparator>
inline void
- parallel_sort_mwms(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp, typename std::iterator_traits<RandomAccessIterator>::difference_type n, int num_threads, bool stable)
+ parallel_sort_mwms(RandomAccessIterator begin, RandomAccessIterator end,
+ Comparator comp,
+ typename std::iterator_traits<RandomAccessIterator>::difference_type n,
+ int num_threads, bool stable)
{
_GLIBCXX_CALL(n)
@@ -366,7 +370,14 @@ namespace __gnu_parallel
#endif
if (Settings::sort_splitting == Settings::SAMPLING)
- sd.samples = new value_type[num_threads * (Settings::sort_mwms_oversampling * num_threads - 1)];
+ {
+ unsigned int sz = Settings::sort_mwms_oversampling * num_threads - 1;
+ sz *= num_threads;
+
+ // Equivalent to value_type[sz], without need of default construction.
+ sz *= sizeof(value_type);
+ sd.samples = static_cast<value_type*>(::operator new(sz));
+ }
else
sd.samples = NULL;
@@ -377,7 +388,9 @@ namespace __gnu_parallel
PMWMSSorterPU<RandomAccessIterator>* pus = new PMWMSSorterPU<RandomAccessIterator>[num_threads];
difference_type* starts = sd.starts = new difference_type[num_threads + 1];
- difference_type chunk_length = n / num_threads, split = n % num_threads, start = 0;
+ difference_type chunk_length = n / num_threads;
+ difference_type split = n % num_threads;
+ difference_type start = 0;
for (int i = 0; i < num_threads; i++)
{
starts[i] = start;
diff --git a/libstdc++-v3/include/parallel/partial_sum.h b/libstdc++-v3/include/parallel/partial_sum.h
index fbba686..e7652c0 100644
--- a/libstdc++-v3/include/parallel/partial_sum.h
+++ b/libstdc++-v3/include/parallel/partial_sum.h
@@ -119,7 +119,7 @@ namespace __gnu_parallel
borders[num_threads + 1] = n;
}
- value_type* sums = new value_type[num_threads];
+ value_type* sums = static_cast<value_type*>(::operator new(sizeof(value_type) * num_threads));
OutputIterator target_end;
#pragma omp parallel num_threads(num_threads)
diff --git a/libstdc++-v3/include/parallel/quicksort.h b/libstdc++-v3/include/parallel/quicksort.h
index 305c8de..a9ceab4 100644
--- a/libstdc++-v3/include/parallel/quicksort.h
+++ b/libstdc++-v3/include/parallel/quicksort.h
@@ -65,10 +65,14 @@ namespace __gnu_parallel
difference_type n = end - begin;
num_samples = std::min(num_samples, n);
- value_type samples[num_samples];
+ value_type* samples = static_cast<value_type*>(__builtin_alloca(sizeof(value_type) * num_samples));
for (difference_type s = 0; s < num_samples; s++)
- samples[s] = begin[(unsigned long long)s * n / num_samples];
+ {
+ const unsigned long long index = static_cast<unsigned long long>(s)
+ * n / num_samples;
+ samples[s] = begin[index];
+ }
__gnu_sequential::sort(samples, samples + num_samples, comp);
diff --git a/libstdc++-v3/include/parallel/random_shuffle.h b/libstdc++-v3/include/parallel/random_shuffle.h
index 7a0f9a1..bb174e1 100644
--- a/libstdc++-v3/include/parallel/random_shuffle.h
+++ b/libstdc++-v3/include/parallel/random_shuffle.h
@@ -203,7 +203,7 @@ namespace __gnu_parallel
offset = sd->dist[s + 1][d->num_threads];
}
- sd->temporaries[iam] = new value_type[offset];
+ sd->temporaries[iam] = static_cast<value_type*>(::operator new(sizeof(value_type) * offset));
t.tic();
@@ -446,7 +446,7 @@ namespace __gnu_parallel
if (num_bins > 1)
{
- value_type* target = new value_type[n];
+ value_type* target = static_cast<value_type*>(::operator new(sizeof(value_type) * n));
bin_index* oracles = new bin_index[n];
difference_type* dist0 = new difference_type[num_bins + 1], * dist1 = new difference_type[num_bins + 1];
diff --git a/libstdc++-v3/include/parallel/settings.h b/libstdc++-v3/include/parallel/settings.h
index 97de007..5cfc6a0 100644
--- a/libstdc++-v3/include/parallel/settings.h
+++ b/libstdc++-v3/include/parallel/settings.h
@@ -165,8 +165,10 @@ namespace
/** @brief Minimal input size for parallel sorting. */
static volatile sequence_index_t sort_minimal_n;
+
/** @brief Oversampling factor for parallel std::sort (MWMS). */
static volatile unsigned int sort_mwms_oversampling;
+
/** @brief Such many samples to take to find a good pivot
(quicksort). */
static volatile unsigned int sort_qs_num_samples_preset;