60 template<
typename ValueType>
76 constexpr static int RADIX = 256;
77 constexpr static int MASK = 0xFF;
121 template<
typename T = ValueType>
123 std::memcpy(dest, src, n *
sizeof(T));
127 template<
typename T = ValueType>
129 for (
size_t i = 0; i < n; ++i) {
160 void sort(
int* keys, ValueType* values,
size_t n) {
166 for (
int pass = 0; pass <
PASSES; ++pass) {
167 int shift = pass * 8;
170#pragma omp parallel for schedule(static)
171 for (
int i = 0; i < n; ++i) {
172 int tid = omp_get_thread_num();
173 int bucket = (keys[i] >> shift) &
MASK;
181 for (
int b = 0; b <
RADIX; ++b) {
182 global[b] += hist[b];
187 std::vector<int> prefix(
RADIX);
189 for (
int b = 0; b <
RADIX; ++b) {
195 std::copy(prefix.begin(), prefix.end(),
localStarts[0].begin());
202 for (
int b = 0; b <
RADIX; ++b) {
203 start[b] = prevStart[b] + prevHist[b];
214#pragma omp parallel for schedule(static)
215 for (
int i = 0; i < n; ++i) {
216 int tid = omp_get_thread_num();
217 int bucket = (keys[i] >> shift) &
MASK;
225#pragma omp parallel for schedule(static)
226 for (
int i = 0; i < n; ++i) {
240 void sort(std::vector<int>& keys, std::vector<ValueType>& values) {
241 if (keys.size() != values.size()) {
242 throw std::runtime_error(
"Key and value arrays must have same size");
244 sort(keys.data(), values.data(), keys.size());
248 void sort(
int* keys, ValueType* values,
size_t start,
size_t end) {
249 if (start >= end)
return;
250 sort(keys + start, values + start, end - start);
265 size_t total =
keyBuffer.capacity() *
sizeof(int);
266 total +=
valueBuffer.capacity() *
sizeof(ValueType);
269 total += hist.capacity() *
sizeof(int);
272 total += start.capacity() *
sizeof(int);
275 total += counter.capacity() *
sizeof(int);
293 template<
typename ValueType>
311 return x == other.
x &&
y == other.
y &&
id == other.
id;
std::vector< ValueType * > valueBuffer
std::vector< int > keyBuffer
void sort(int *keys, ValueType *values, size_t start, size_t end)
void setNumThreads(int threads)
static constexpr int MASK
void copyValues(T *dest, const T *src, size_t n, enable_if_not_trivially_copyable< T > *=nullptr)
OptimizedRadixSorter(size_t maxSize)
static constexpr int PASSES
void sort(int *keys, ValueType *values, size_t n)
std::vector< int > globalHist
std::vector< ValueType > valueBuffer
std::vector< std::vector< int > > localStarts
size_t getMemoryUsage() const
void ensureCapacity(size_t n)
std::vector< int > keyBuffer
void initializeThreadData(int threads)
std::vector< std::vector< int > > localCounters
void sort(std::vector< int > &keys, std::vector< ValueType > &values)
static constexpr int RADIX
void copyValues(T *dest, const T *src, size_t n, enable_if_trivially_copyable< T > *=nullptr)
int getNumThreads() const
std::vector< std::vector< int > > histThreads
typename std::enable_if< std::is_trivially_copyable< T >::value >::type enable_if_trivially_copyable
typename std::enable_if<!std::is_trivially_copyable< T >::value >::type enable_if_not_trivially_copyable
ComplexData(double _x, double _y, int _id)
bool operator==(const ComplexData &other) const