/* LICENCE: CC3 - look it up, you need to mention me but that is all */ /* 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! // Uncomment and give a value for input being modulo this value! //#define INPUT_MOD (65536*128) // Number of input elements to generate - unused when CREEL is defined! #define SORT_WIDTH 100000000 //#define SORT_WIDTH 40000000 // 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 // Uncomment if you want to see how many elements are unique and duplicant in the input (debugging info) // #define COUNT_DUPLICANTS //#define SKA_SORT // Uncomment for perf / cachegring and similar runs! #define MEASURE_ONLY // Uncomment this for performance measuring with "coz" // XXX: Beware that we will do this many times of sorts! //#define COZ_MEASURE 400 /* Includes */ #include #include #include #include // std::rand | rand #include #include #include // std::sort #define MAGYAR_SORT_DEFAULT_REUSE #include "magyarsort.h" #ifdef SKA_SORT #include "ska_sort.hpp" #endif // SKA_SORT #ifdef COZ_MEASURE #include "coz.h" #endif // COZ_MEASURE /* Input generation and prerequisites */ #ifdef CREEL #define MAGYAR_SORT_NIBBLE #define PRINT_OUTPUT static inline std::vector 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 ret; ret.resize(16); memcpy(&ret[0], CreelHex, sizeof(CreelHex)); return ret; } #else // Randomized values, no overrides static inline std::vector GenerateInput() { std::vector ret; ret.resize(SORT_WIDTH); for(size_t ek = 0; ek < SORT_WIDTH; ++ek) { #ifndef INPUT_MOD ret[ek] = (uint32_t)std::rand(); #else ret[ek] = (uint32_t)std::rand() % INPUT_MOD; #endif } return ret; } #endif /* Test entry point */ int main() { /* Input */ std::vector in1 = GenerateInput();; std::vector in2 = in1; // copy #ifndef MEASURE_ONLY auto stdBegin = std::chrono::high_resolution_clock::now(); #ifndef SKA_SORT /* std::sort */ std::sort(std::begin(in2), std::end(in2)); #else // SKA_SORT /* Ska-sort */ //ska_sort(std::begin(in2), std::end(in2)); std::vector buffer(in2.size()); if (ska_sort_copy(std::begin(in2), std::end(in2), std::begin(buffer))) in2.swap(buffer); #endif // SKA_SORT auto stdEnd = std::chrono::high_resolution_clock::now(); #ifdef PRINT_OUTPUT printf("std: "); MagyarSort::debugArr(&in2[0], in2.size()); #endif // PRINT_OUTPUT #endif // !MEASURE_ONLY 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(); #ifdef COZ_MEASURE std::vector in_coz_common = GenerateInput();; for(int i = 0; i < COZ_MEASURE; ++i) { std::vector 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 #ifdef PRINT_OUTPUT printf("Our: "); MagyarSort::debugArr(arr1, in1.size()); #endif // PRINT_OUTPUT /* Check against std - the real test */ #ifndef MEASURE_ONLY bool good = true; #ifdef COUNT_DUPLICANTS size_t dups = 0; uint32_t prev = (in1.size() > 0) ? in1[0] : 0; #endif // COUNT_DUPLICANTS for(size_t i = 0; good && (i < in1.size()); ++i) { good &= (in1[i] == in2[i]); #ifdef COUNT_DUPLICANTS if(i > 0) { uint32_t curr = in1[i]; if(curr == prev) { ++dups; } else { prev = curr; } } #endif // COUNT_DUPLICANTS } #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 #endif // !MEASURE_ONLY printf("Results:\n\n"); printf("- Sorted %zu elements", in1.size()); #ifndef MEASURE_ONLY if(good) printf("- Same result as known sort result!\n"); else printf("- Differs from known sort result! Error!\n"); printf("\n"); auto stdElapsed = std::chrono::duration_cast(stdEnd - stdBegin); #endif // !MEASURE_ONLY auto ourElapsed = std::chrono::duration_cast(ourEnd - ourBegin); #ifndef MEASURE_ONLY #ifdef SKA_SORT printf("Time (ska sort): %.3f ms.\n", stdElapsed.count() * 1e-6); #else printf("Time (std sort): %.3f ms.\n", stdElapsed.count() * 1e-6); #endif #endif // !MEASURE_ONLY printf("Time (our sort): %.3f ms.\n", ourElapsed.count() * 1e-6); return 0; }