#include #include #include #include #include #include #include #include #include // ------------------------------------------------------------------- // ------------------------------------------------------------------- class Timer { public: Timer(std::string name) : _name(name), _start(std::chrono::high_resolution_clock::now()) {} ~Timer() { std::chrono::duration elapsed_seconds = std::chrono::high_resolution_clock::now() - _start; printf("%s: %.3fs\n", _name.c_str(), elapsed_seconds.count()); } private: std::string _name; std::chrono::high_resolution_clock::time_point _start; }; // -------------------------------------------------------------------------- // from: https://github.com/preshing/RandomSequence // -------------------------------------------------------------------------- class RSU { private: uint32_t m_index; uint32_t m_intermediateOffset; static uint32_t permuteQPR(uint32_t x) { static const uint32_t prime = 4294967291u; if (x >= prime) return x; // The 5 integers out of range are mapped to themselves. uint32_t residue = ((unsigned long long) x * x) % prime; return (x <= prime / 2) ? residue : prime - residue; } public: RSU(uint32_t seedBase, uint32_t seedOffset) { m_index = permuteQPR(permuteQPR(seedBase) + 0x682f0161); m_intermediateOffset = permuteQPR(permuteQPR(seedOffset) + 0x46790905); } uint32_t next() { return permuteQPR((permuteQPR(m_index++) + m_intermediateOffset) ^ 0x5bf03635); } }; // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- template void test(const char *name, std::function &)> perturb) { Set s; unsigned int seed = 76687; RSU rsu(seed, seed + 1); for (uint32_t i=0; i order(s.begin(), s.end()); perturb(order); order.resize(N/4); Timer t(name); Set c(order.begin(), order.end()); } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- int main() { auto shuffle = [](std::vector &order) { std::random_device rd; std::mt19937 g(rd()); std::shuffle(order.begin(), order.end(), g); }; auto noop = [](std::vector &) {}; test, 10000000>("ordered", noop); test, 10000000>("shuffled", shuffle); test, 10000000>("parallel ordered", noop); test, 10000000>("parallel shuffled", shuffle); }