@@ -34,124 +34,94 @@ type_t next_value(type_t value)
34
34
template <typename vtype, typename mm_t >
35
35
X86_SIMD_SORT_INLINE void COEX (mm_t &a, mm_t &b);
36
36
37
- template <typename vtype>
38
- struct AscendingComparator {
37
+ template <typename vtype, bool descend >
38
+ struct Comparator {
39
39
using reg_t = typename vtype::reg_t ;
40
40
using opmask_t = typename vtype::opmask_t ;
41
41
using type_t = typename vtype::type_t ;
42
42
43
43
X86_SIMD_SORT_FINLINE bool STDSortComparator (const type_t &a,
44
44
const type_t &b)
45
45
{
46
- return comparison_func<vtype>(a, b);
46
+ if constexpr (descend) { return comparison_func<vtype>(b, a); }
47
+ else {
48
+ return comparison_func<vtype>(a, b);
49
+ }
47
50
}
48
51
49
52
X86_SIMD_SORT_FINLINE opmask_t PartitionComparator (reg_t a, reg_t b)
50
53
{
51
- return vtype::ge (a, b);
54
+ if constexpr (descend) { return vtype::ge (b, a); }
55
+ else {
56
+ return vtype::ge (a, b);
57
+ }
52
58
}
53
59
54
60
X86_SIMD_SORT_FINLINE void COEX (reg_t &a, reg_t &b)
55
61
{
56
- ::COEX<vtype, reg_t >(a, b);
62
+ if constexpr (descend) { ::COEX<vtype, reg_t >(b, a); }
63
+ else {
64
+ ::COEX<vtype, reg_t >(a, b);
65
+ }
57
66
}
58
67
59
68
// Returns a vector of values that would be sorted as far right as possible
60
69
// For ascending order, this is the maximum possible value
61
70
X86_SIMD_SORT_FINLINE reg_t rightmostPossibleVec ()
62
71
{
63
- return vtype::zmm_max ();
72
+ if constexpr (descend) { return vtype::zmm_min (); }
73
+ else {
74
+ return vtype::zmm_max ();
75
+ }
64
76
}
65
77
66
78
// Returns the value that would be leftmost of the two when sorted
67
79
// For ascending order, that is the smaller value
68
80
X86_SIMD_SORT_FINLINE type_t leftmost (type_t smaller, type_t larger)
69
81
{
70
- UNUSED (larger);
71
- return smaller;
82
+ if constexpr (descend) {
83
+ UNUSED (smaller);
84
+ return larger;
85
+ }
86
+ else {
87
+ UNUSED (larger);
88
+ return smaller;
89
+ }
72
90
}
73
91
74
92
// Returns the value that would be rightmost of the two when sorted
75
93
// For ascending order, that is the larger value
76
94
X86_SIMD_SORT_FINLINE type_t rightmost (type_t smaller, type_t larger)
77
95
{
78
- UNUSED (smaller);
79
- return larger;
96
+ if constexpr (descend) {
97
+ UNUSED (larger);
98
+ return smaller;
99
+ }
100
+ else {
101
+ UNUSED (smaller);
102
+ return larger;
103
+ }
80
104
}
81
105
82
106
// If median == smallest, that implies approximately half the array is equal to smallest, unless we were very unlucky with our sample
83
107
// Try just doing the next largest value greater than this seemingly very common value to seperate them out
84
108
X86_SIMD_SORT_FINLINE type_t choosePivotMedianIsSmallest (type_t median)
85
109
{
86
- return next_value<type_t >(median);
110
+ if constexpr (descend) { return median; }
111
+ else {
112
+ return next_value<type_t >(median);
113
+ }
87
114
}
88
115
89
116
// If median == largest, that implies approximately half the array is equal to largest, unless we were very unlucky with our sample
90
117
// Thus, median probably is a fine pivot, since it will move all of this common value into its own partition
91
118
X86_SIMD_SORT_FINLINE type_t choosePivotMedianIsLargest (type_t median)
92
119
{
93
- return median;
94
- }
95
- };
96
-
97
- template <typename vtype>
98
- struct DescendingComparator {
99
- using reg_t = typename vtype::reg_t ;
100
- using opmask_t = typename vtype::opmask_t ;
101
- using type_t = typename vtype::type_t ;
102
-
103
- X86_SIMD_SORT_FINLINE bool STDSortComparator (const type_t &a,
104
- const type_t &b)
105
- {
106
- return comparison_func<vtype>(b, a);
107
- }
108
-
109
- X86_SIMD_SORT_FINLINE opmask_t PartitionComparator (reg_t a, reg_t b)
110
- {
111
- return vtype::ge (b, a);
112
- }
113
-
114
- X86_SIMD_SORT_FINLINE void COEX (reg_t &a, reg_t &b)
115
- {
116
- ::COEX<vtype, reg_t >(b, a);
117
- }
118
-
119
- // Returns a vector of values that would be sorted as far right as possible
120
- // For descending order, this is the minimum possible value
121
- X86_SIMD_SORT_FINLINE reg_t rightmostPossibleVec ()
122
- {
123
- return vtype::zmm_min ();
124
- }
125
-
126
- // Returns the value that would be leftmost of the two when sorted
127
- // For descending order, that is the larger value
128
- X86_SIMD_SORT_FINLINE type_t leftmost (type_t smaller, type_t bigger)
129
- {
130
- UNUSED (smaller);
131
- return bigger;
132
- }
133
-
134
- // Returns the value that would be rightmost of the two when sorted
135
- // For descending order, that is the smaller value
136
- X86_SIMD_SORT_FINLINE type_t rightmost (type_t smaller, type_t bigger)
137
- {
138
- UNUSED (bigger);
139
- return smaller;
140
- }
141
-
142
- // If median == smallest, that implies approximately half the array is equal to smallest, unless we were very unlucky with our sample
143
- // Thus, median probably is a fine pivot, since it will move all of this common value into its own partition
144
- X86_SIMD_SORT_FINLINE type_t choosePivotMedianIsSmallest (type_t median)
145
- {
146
- return median;
147
- }
148
-
149
- // If median == largest, that implies approximately half the array is equal to largest, unless we were very unlucky with our sample
150
- // Try just doing the next smallest value less than this seemingly very common value to seperate them out
151
- X86_SIMD_SORT_FINLINE type_t choosePivotMedianIsLargest (type_t median)
152
- {
153
- return prev_value<type_t >(median);
120
+ if constexpr (descend) { return prev_value<type_t >(median); }
121
+ else {
122
+ return median;
123
+ }
154
124
}
155
125
};
156
126
157
- #endif // XSS_COMMON_COMPARATORS
127
+ #endif // XSS_COMMON_COMPARATORS
0 commit comments