2021-03-11 21:22:37 +01:00
|
|
|
/* LICENCE: CC3 - look it up, you need to mention me but that is all */
|
|
|
|
|
|
2021-03-13 15:51:24 +01:00
|
|
|
/* CONFIG */
|
|
|
|
|
|
|
|
|
|
// Uncomment next line to follow Creel: https://www.youtube.com/watch?v=ujb2CIWE8zY
|
|
|
|
|
// #define CREEL // Overwrites TEST_LEN to 16 and sets MAGYAR_SORT_NIBBLE!
|
|
|
|
|
|
2022-09-01 01:56:15 +02:00
|
|
|
// Uncomment and give a value for input being modulo this value!
|
|
|
|
|
//#define INPUT_MOD (65536*128)
|
|
|
|
|
|
2021-03-13 15:51:24 +01:00
|
|
|
// Number of input elements to generate - unused when CREEL is defined!
|
2022-09-01 01:56:15 +02:00
|
|
|
//#define SORT_WIDTH 200000000
|
|
|
|
|
#define SORT_WIDTH 40000000
|
2021-03-13 15:51:24 +01:00
|
|
|
// Uncomment this to use nibbles as digits and not bytes - CREEL defines this anyways
|
|
|
|
|
//#define MAGYAR_SORT_NIBBLE
|
|
|
|
|
|
|
|
|
|
// Uncomment if you want to see output before / after sorts (debugging for example)
|
|
|
|
|
//#define PRINT_OUTPUT
|
|
|
|
|
|
2022-09-01 01:56:15 +02:00
|
|
|
// Uncomment if you want to see how many elements are unique and duplicant in the input (debugging info)
|
|
|
|
|
#define COUNT_DUPLICANTS
|
|
|
|
|
|
2021-12-14 17:29:33 +01:00
|
|
|
//#define SKA_SORT
|
2021-12-13 00:51:26 +01:00
|
|
|
|
2021-12-13 03:48:01 +01:00
|
|
|
// Uncomment for perf / cachegring and similar runs!
|
|
|
|
|
#define MEASURE_ONLY
|
|
|
|
|
|
2021-12-14 17:29:33 +01:00
|
|
|
// Uncomment this for performance measuring with "coz"
|
|
|
|
|
// XXX: Beware that we will do this many times of sorts!
|
2021-12-14 17:32:43 +01:00
|
|
|
//#define COZ_MEASURE 400
|
2021-12-14 17:29:33 +01:00
|
|
|
|
2021-03-13 15:51:24 +01:00
|
|
|
/* Includes */
|
|
|
|
|
|
|
|
|
|
#include <cstring>
|
2021-03-11 21:22:37 +01:00
|
|
|
#include <cstdint>
|
2021-03-11 21:38:06 +01:00
|
|
|
#include <cstdio>
|
2021-03-13 15:51:24 +01:00
|
|
|
#include <cstdlib> // std::rand | rand
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <chrono>
|
|
|
|
|
#include <algorithm> // std::sort
|
2021-12-15 03:14:35 +01:00
|
|
|
|
|
|
|
|
#define MAGYAR_SORT_DEFAULT_REUSE
|
2021-03-11 21:22:37 +01:00
|
|
|
#include "magyarsort.h"
|
|
|
|
|
|
2021-12-13 00:51:26 +01:00
|
|
|
#ifdef SKA_SORT
|
|
|
|
|
#include "ska_sort.hpp"
|
|
|
|
|
#endif // SKA_SORT
|
|
|
|
|
|
2021-12-14 17:29:33 +01:00
|
|
|
#ifdef COZ_MEASURE
|
|
|
|
|
#include "coz.h"
|
|
|
|
|
#endif // COZ_MEASURE
|
|
|
|
|
|
2021-03-13 15:51:24 +01:00
|
|
|
/* Input generation and prerequisites */
|
|
|
|
|
|
|
|
|
|
#ifdef CREEL
|
|
|
|
|
#define MAGYAR_SORT_NIBBLE
|
|
|
|
|
#define PRINT_OUTPUT
|
|
|
|
|
static inline std::vector<uint32_t> GenerateInput() {
|
|
|
|
|
static constexpr uint32_t CreelHex[16] = {
|
|
|
|
|
// Homage to https://www.youtube.com/watch?v=ujb2CIWE8zY haha
|
|
|
|
|
// When doing nibbles these are visible all throughout all the
|
|
|
|
|
// steps and these will be easily readable in debugger in hex!
|
|
|
|
|
0x277,
|
|
|
|
|
0x806,
|
|
|
|
|
0x681,
|
|
|
|
|
0x462,
|
|
|
|
|
0x787,
|
|
|
|
|
0x163,
|
|
|
|
|
0x284,
|
|
|
|
|
0x166,
|
|
|
|
|
0x905,
|
|
|
|
|
0x518,
|
|
|
|
|
0x263,
|
|
|
|
|
0x395,
|
|
|
|
|
0x988,
|
|
|
|
|
0x307,
|
|
|
|
|
0x779,
|
|
|
|
|
0x721
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::vector<uint32_t> ret;
|
|
|
|
|
ret.resize(16);
|
|
|
|
|
|
|
|
|
|
memcpy(&ret[0], CreelHex, sizeof(CreelHex));
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
// Randomized values, no overrides
|
|
|
|
|
static inline std::vector<uint32_t> GenerateInput() {
|
|
|
|
|
std::vector<uint32_t> ret;
|
|
|
|
|
ret.resize(SORT_WIDTH);
|
|
|
|
|
|
|
|
|
|
for(size_t ek = 0; ek < SORT_WIDTH; ++ek) {
|
2022-09-01 01:56:15 +02:00
|
|
|
#ifndef INPUT_MOD
|
2021-03-13 15:51:24 +01:00
|
|
|
ret[ek] = (uint32_t)std::rand();
|
2022-09-01 01:56:15 +02:00
|
|
|
#else
|
|
|
|
|
ret[ek] = (uint32_t)std::rand() % INPUT_MOD;
|
|
|
|
|
#endif
|
2021-03-13 15:51:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Test entry point */
|
|
|
|
|
|
2021-03-11 21:22:37 +01:00
|
|
|
int main() {
|
2021-03-13 15:51:24 +01:00
|
|
|
/* Input */
|
|
|
|
|
std::vector<uint32_t> in1 = GenerateInput();;
|
|
|
|
|
std::vector<uint32_t> in2 = in1; // copy
|
|
|
|
|
|
2021-12-13 03:48:01 +01:00
|
|
|
#ifndef MEASURE_ONLY
|
2021-03-13 15:51:24 +01:00
|
|
|
auto stdBegin = std::chrono::high_resolution_clock::now();
|
2021-12-13 00:51:26 +01:00
|
|
|
#ifndef SKA_SORT
|
|
|
|
|
/* std::sort */
|
2021-03-13 15:51:24 +01:00
|
|
|
std::sort(std::begin(in2), std::end(in2));
|
2021-12-13 00:51:26 +01:00
|
|
|
#else // SKA_SORT
|
|
|
|
|
/* Ska-sort */
|
|
|
|
|
//ska_sort(std::begin(in2), std::end(in2));
|
|
|
|
|
std::vector<uint32_t> buffer(in2.size());
|
|
|
|
|
if (ska_sort_copy(std::begin(in2), std::end(in2), std::begin(buffer))) in2.swap(buffer);
|
|
|
|
|
#endif // SKA_SORT
|
2021-03-13 15:51:24 +01:00
|
|
|
auto stdEnd = std::chrono::high_resolution_clock::now();
|
|
|
|
|
|
|
|
|
|
#ifdef PRINT_OUTPUT
|
|
|
|
|
printf("std: ");
|
|
|
|
|
MagyarSort::debugArr(&in2[0], in2.size());
|
|
|
|
|
#endif // PRINT_OUTPUT
|
|
|
|
|
|
2021-12-13 03:48:01 +01:00
|
|
|
#endif // !MEASURE_ONLY
|
|
|
|
|
|
2021-12-13 02:18:08 +01:00
|
|
|
uint32_t *arr1 = &(in1[0]);
|
|
|
|
|
|
|
|
|
|
#ifdef PRINT_OUTPUT
|
|
|
|
|
printf("Inp: ");
|
|
|
|
|
MagyarSort::debugArr(arr1, in1.size());
|
|
|
|
|
#endif // PRINT_OUTPUT
|
|
|
|
|
|
|
|
|
|
/* Our sort */
|
|
|
|
|
auto ourBegin = std::chrono::high_resolution_clock::now();
|
|
|
|
|
MagyarSort::sort(arr1, in1.size());
|
|
|
|
|
auto ourEnd = std::chrono::high_resolution_clock::now();
|
|
|
|
|
|
2021-12-14 17:29:33 +01:00
|
|
|
#ifdef COZ_MEASURE
|
|
|
|
|
std::vector<uint32_t> in_coz_common = GenerateInput();;
|
|
|
|
|
for(int i = 0; i < COZ_MEASURE; ++i) {
|
|
|
|
|
std::vector<uint32_t> in_coz = in_coz_common; // cpy
|
|
|
|
|
|
|
|
|
|
uint32_t *arr_coz = &(in_coz[0]);
|
|
|
|
|
|
|
|
|
|
MagyarSort::sort(arr1, in1.size());
|
|
|
|
|
COZ_PROGRESS_NAMED("magyarsort_progress");
|
|
|
|
|
|
|
|
|
|
if((i % 128) == 0) { printf("%d / %d\n", i, COZ_MEASURE); }
|
|
|
|
|
}
|
|
|
|
|
#endif // COZ_MEASURE
|
|
|
|
|
|
2021-12-13 02:18:08 +01:00
|
|
|
#ifdef PRINT_OUTPUT
|
|
|
|
|
printf("Our: ");
|
|
|
|
|
MagyarSort::debugArr(arr1, in1.size());
|
|
|
|
|
#endif // PRINT_OUTPUT
|
|
|
|
|
|
2021-03-13 15:51:24 +01:00
|
|
|
/* Check against std - the real test */
|
2021-03-11 21:22:37 +01:00
|
|
|
|
2021-12-13 03:48:01 +01:00
|
|
|
#ifndef MEASURE_ONLY
|
2022-08-31 12:56:51 +02:00
|
|
|
bool good = true;
|
2022-09-01 01:56:15 +02:00
|
|
|
#ifdef COUNT_DUPLICANTS
|
|
|
|
|
size_t dups = 0;
|
|
|
|
|
uint32_t prev = (in1.size() > 0) ? in1[0] : 0;
|
|
|
|
|
#endif // COUNT_DUPLICANTS
|
2021-03-13 15:51:24 +01:00
|
|
|
for(size_t i = 0; good && (i < in1.size()); ++i) {
|
|
|
|
|
good &= (in1[i] == in2[i]);
|
2022-09-01 01:56:15 +02:00
|
|
|
#ifdef COUNT_DUPLICANTS
|
|
|
|
|
if(i > 0) {
|
|
|
|
|
uint32_t curr = in1[i];
|
|
|
|
|
if(curr == prev) {
|
|
|
|
|
++dups;
|
|
|
|
|
} else {
|
|
|
|
|
prev = curr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif // COUNT_DUPLICANTS
|
2021-03-13 15:51:24 +01:00
|
|
|
}
|
2022-09-01 01:56:15 +02:00
|
|
|
#ifdef COUNT_DUPLICANTS
|
|
|
|
|
printf("Duplications are %d out of %d, which is %f percent\n", dups, in1.size(), (float)(dups * 100) / in1.size());
|
|
|
|
|
#endif // COUNT_DUPLICANTS
|
|
|
|
|
|
2021-12-13 03:48:01 +01:00
|
|
|
#endif // !MEASURE_ONLY
|
2021-03-11 21:22:37 +01:00
|
|
|
|
2021-03-13 15:51:24 +01:00
|
|
|
printf("Results:\n\n");
|
|
|
|
|
printf("- Sorted %zu elements", in1.size());
|
2021-12-13 03:48:01 +01:00
|
|
|
#ifndef MEASURE_ONLY
|
2021-12-14 17:29:33 +01:00
|
|
|
if(good) printf("- Same result as known sort result!\n");
|
|
|
|
|
else printf("- Differs from known sort result! Error!\n");
|
2021-03-13 15:51:24 +01:00
|
|
|
printf("\n");
|
|
|
|
|
auto stdElapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(stdEnd - stdBegin);
|
2021-12-13 03:48:01 +01:00
|
|
|
#endif // !MEASURE_ONLY
|
2021-03-13 15:51:24 +01:00
|
|
|
auto ourElapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(ourEnd - ourBegin);
|
2021-12-13 03:48:01 +01:00
|
|
|
#ifndef MEASURE_ONLY
|
2021-12-14 17:29:33 +01:00
|
|
|
#ifdef SKA_SORT
|
|
|
|
|
printf("Time (ska sort): %.3f ms.\n", stdElapsed.count() * 1e-6);
|
|
|
|
|
#else
|
2021-03-13 15:51:24 +01:00
|
|
|
printf("Time (std sort): %.3f ms.\n", stdElapsed.count() * 1e-6);
|
2021-12-14 17:29:33 +01:00
|
|
|
#endif
|
2021-12-13 03:48:01 +01:00
|
|
|
#endif // !MEASURE_ONLY
|
2021-03-13 15:51:24 +01:00
|
|
|
printf("Time (our sort): %.3f ms.\n", ourElapsed.count() * 1e-6);
|
2021-03-11 21:22:37 +01:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|