Skip to content

Commit 909ce2b

Browse files
committed
MSVS C++11 support
1 parent 036a7e8 commit 909ce2b

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

placement_sort.h

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <memory>
2020
#include <vector>
21+
#include <array>
2122
#include <limits>
2223
#include <cmath>
2324

@@ -249,6 +250,24 @@ class ElementAccessor {
249250
};
250251

251252

253+
template<typename T>
254+
inline bool isfinite(T& t) {
255+
return true;
256+
}
257+
258+
259+
template<>
260+
inline bool isfinite<double>(double& t) {
261+
return std::isfinite(t);
262+
}
263+
264+
template<>
265+
inline bool isfinite<float>(float& t) {
266+
return std::isfinite(t);
267+
}
268+
269+
270+
252271
template <typename T, typename TElementAccessor>
253272
class Statistics {
254273
/* Finds finite min and max values in the array
@@ -263,7 +282,7 @@ class Statistics {
263282
sorted = true;
264283

265284
if _PLACEMENT_SORT_CONSTEXPR (std::numeric_limits<T>::has_infinity) {
266-
while(!std::isfinite(prev_value) && first_finite_i < size) {
285+
while(!isfinite(prev_value) && first_finite_i < size) {
267286
++first_finite_i;
268287
const T value = array.get_value(first_finite_i);
269288
if (value < prev_value)
@@ -281,7 +300,7 @@ class Statistics {
281300
sorted = false;
282301
prev_value = value;
283302
if _PLACEMENT_SORT_CONSTEXPR (std::numeric_limits<T>::has_infinity)
284-
if (!std::isfinite(value))
303+
if (!isfinite(value))
285304
continue;
286305
if (value < min)
287306
min = value;
@@ -340,10 +359,10 @@ class PlaceCalculator<T, TStatistics, typename std::enable_if<std::is_floating_p
340359
PlaceCalculator(const TStatistics& statistics, size_t size) : min(statistics.get_min()), last_index(size - 1) {
341360
T max = statistics.get_max();
342361
invariant = ((long double)size - 1.) / (max - min);
343-
if (!std::isfinite(invariant) || invariant == 0.) {
362+
if (!isfinite(invariant) || invariant == 0.) {
344363
split = true;
345364
split_value = (0.5 * max + 0.5 * min);
346-
if (!std::isfinite(split_value))
365+
if (!isfinite(split_value))
347366
split_value = max;
348367
}
349368
}
@@ -373,7 +392,7 @@ class PlaceCalculator<T, TStatistics, typename std::enable_if<std::is_floating_p
373392
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
374393
template<typename T>
375394
static inline void prefetch(T p) {
376-
_mm_prefetch(p, _MM_HINT_NTA);
395+
_mm_prefetch((char*)p, _MM_HINT_NTA);
377396
}
378397
#else
379398
template<typename T>
@@ -429,20 +448,22 @@ template <typename TElementAccessor, typename TPlaceCalculator, typename counter
429448
static inline void move_elements_in_place(TElementAccessor& array, const TPlaceCalculator& placer, counters_t& counters) {
430449
const size_t size = array.get_count();
431450
constexpr typename counters_t::value_type topBit = (typename counters_t::value_type)1 << (sizeof(typename counters_t::value_type)*8 - 1);
432-
const size_t block_size = (size > 512*1024) ? 32 : 4;
451+
constexpr size_t block_size_high = 32;
452+
constexpr size_t block_size_low = 4;
453+
const size_t block_size = (size > 512*1024) ? block_size_high : block_size_low;
433454

434455
/* This algorithm moves elements to their places and sorts out collisions with no extra memory except already available counters.
435456
* It uses highest bit in counters to mark elements which are already moved to their destination place.
436457
* This way is fastest though looks ugly. It saves memory traffic. */
437458

438459
for (size_t sorted = 0; sorted < size; ) {
439-
size_t places[block_size];
460+
size_t places[block_size_high];
440461
const size_t block_end = sorted + std::min(block_size, size - sorted);
441462
for (size_t i = sorted; i < block_end; ++i) { // prefetch counters
442463
if (!(topBit & counters[i])) {
443464
const size_t place = placer.get_place(array.get_value(i));
444465
places[i - sorted] = place;
445-
_mm_prefetch(&counters[place], _MM_HINT_NTA);
466+
prefetch(&counters[place]);
446467
}
447468
}
448469
for (size_t i = sorted; i < block_end; ++i) { // move
@@ -707,7 +728,7 @@ void placement_sort(TElementAccessor& array) {
707728
}
708729

709730
/* TODO:
710-
* MSVS C++11 support
731+
* Fix MSVS low performance
711732
* port tests
712733
* topBit hider functors
713734
* fix (36, initFexpGrowth<float> non buff case

0 commit comments

Comments
 (0)