my_type min_value() const { #if LOAD return my_type(std::numeric_limits<my_type::key_type>::max(), MAGIC); #else return my_type(std::numeric_limits<my_type::key_type>::max()); #endif }
static my_type cast_to(const Scalar::Base& value) { return my_type(value.int_value()); }
int main(int argc, char* argv[]) { if (argc < 3) { std::cout << "Usage: " << argv[0] << " [n in MiB]" #if defined(STXXL_PARALLEL) << " [p threads]" #endif << std::endl; return -1; } STXXL_MSG("----------------------------------------"); stxxl::config::get_instance(); std::string Flags = std::string("") #if STXXL_CHECK_ORDER_IN_SORTS + " STXXL_CHECK_ORDER_IN_SORTS" #endif #ifdef NDEBUG + " NDEBUG" #endif #if TINY_PQ + " TINY_PQ" #endif #if MANUAL_PQ + " MANUAL_PQ" #endif #if SIDE_PQ + " SIDE_PQ" #endif #if STXXL_PARALLEL_PQ_MULTIWAY_MERGE_INTERNAL + " STXXL_PARALLEL_PQ_MULTIWAY_MERGE_INTERNAL" #endif #if STXXL_PARALLEL_PQ_MULTIWAY_MERGE_EXTERNAL + " STXXL_PARALLEL_PQ_MULTIWAY_MERGE_EXTERNAL" #endif #if STXXL_PARALLEL_PQ_MULTIWAY_MERGE_DELETE_BUFFER + " STXXL_PARALLEL_PQ_MULTIWAY_MERGE_DELETE_BUFFER" #endif ; STXXL_MSG("Flags:" << Flags); unsigned long megabytes = atoi(argv[1]); #if defined(STXXL_PARALLEL_MODE) int num_threads = atoi(argv[2]); STXXL_MSG("Threads: " << num_threads); omp_set_num_threads(num_threads); __gnu_parallel::_Settings parallel_settings(__gnu_parallel::_Settings::get()); parallel_settings.sort_algorithm = __gnu_parallel::QS_BALANCED; parallel_settings.sort_splitting = __gnu_parallel::SAMPLING; parallel_settings.sort_minimal_n = 1000; parallel_settings.sort_mwms_oversampling = 10; parallel_settings.merge_splitting = __gnu_parallel::SAMPLING; parallel_settings.merge_minimal_n = 1000; parallel_settings.merge_oversampling = 10; parallel_settings.multiway_merge_algorithm = __gnu_parallel::LOSER_TREE; parallel_settings.multiway_merge_splitting = __gnu_parallel::EXACT; parallel_settings.multiway_merge_oversampling = 10; parallel_settings.multiway_merge_minimal_n = 1000; parallel_settings.multiway_merge_minimal_k = 2; __gnu_parallel::_Settings::set(parallel_settings); #endif const stxxl::unsigned_type mem_for_queue = 512 * mega; const stxxl::unsigned_type mem_for_pools = 512 * mega; #if TINY_PQ stxxl::STXXL_UNUSED(mem_for_queue); const unsigned BufferSize1 = 32; // equalize procedure call overheads etc. const unsigned N = (1 << 9) / sizeof(my_type); // minimal sequence length const unsigned IntKMAX = 8; // maximal arity for internal mergersq const unsigned IntLevels = 2; // number of internal levels const unsigned BlockSize = (4 * mega); const unsigned ExtKMAX = 8; // maximal arity for external mergers const unsigned ExtLevels = 2; // number of external levels typedef stxxl::priority_queue< stxxl::priority_queue_config< my_type, my_cmp, BufferSize1, N, IntKMAX, IntLevels, BlockSize, ExtKMAX, ExtLevels > > pq_type; #elif MANUAL_PQ stxxl::STXXL_UNUSED(mem_for_queue); const unsigned BufferSize1 = 32; // equalize procedure call overheads etc. const unsigned N = (1 << 20) / sizeof(my_type); // minimal sequence length const unsigned IntKMAX = 16; // maximal arity for internal mergersq const unsigned IntLevels = 2; // number of internal levels const unsigned BlockSize = (4 * mega); const unsigned ExtKMAX = 32; // maximal arity for external mergers const unsigned ExtLevels = 2; // number of external levels typedef stxxl::priority_queue< stxxl::priority_queue_config< my_type, my_cmp, BufferSize1, N, IntKMAX, IntLevels, BlockSize, ExtKMAX, ExtLevels > > pq_type; #else const stxxl::uint64 volume = stxxl::uint64(200000) * mega; // in bytes typedef stxxl::PRIORITY_QUEUE_GENERATOR<my_type, my_cmp, mem_for_queue, volume / sizeof(my_type) / 1024 + 1> gen; typedef gen::result pq_type; // BufferSize1 = Config::BufferSize1, // N = Config::N, // IntKMAX = Config::IntKMAX, // IntLevels = Config::IntLevels, // ExtLevels = Config::ExtLevels, // Levels = Config::IntLevels + Config::ExtLevels, // BlockSize = Config::BlockSize, // ExtKMAX = Config::ExtKMAX /* STXXL_MSG ( "Blocks fitting into internal memory m: "<<gen::m ); STXXL_MSG ( "X : "<<gen::X ); //maximum number of internal elements //X = B * (settings::k - m) / settings::E, STXXL_MSG ( "Expected internal memory consumption: "<< (gen::EConsumption / 1048576) << " MiB");*/ #endif STXXL_MSG("Internal arity: " << pq_type::IntKMAX); STXXL_MSG("N : " << pq_type::N); //X / (AI * AI) STXXL_MSG("External arity: " << pq_type::ExtKMAX); STXXL_MSG("Block size B: " << pq_type::BlockSize); //EConsumption = X * settings::E + settings::B * AE + ((MaxS_ / X) / AE) * settings::B * 1024 STXXL_MSG("Data type size: " << sizeof(my_type)); STXXL_MSG(""); stxxl::stats_data sd_start(*stxxl::stats::get_instance()); stxxl::timer Timer; Timer.start(); pq_type p(mem_for_pools / 2, mem_for_pools / 2); stxxl::int64 nelements = stxxl::int64(megabytes * mega / sizeof(my_type)), i; STXXL_MSG("Internal memory consumption of the priority queue: " << p.mem_cons() << " B"); STXXL_MSG("Peak number of elements (n): " << nelements); STXXL_MSG("Max number of elements to contain: " << (stxxl::uint64(pq_type::N) * pq_type::IntKMAX * pq_type::IntKMAX * pq_type::ExtKMAX * pq_type::ExtKMAX)); srand(5); my_cmp cmp; my_key_type r, sum_input = 0, sum_output = 0; my_type least(0), last_least(0); const my_key_type modulo = 0x10000000; #if SIDE_PQ std::priority_queue<my_type, std::vector<my_type>, my_cmp> side_pq; #endif my_type side_pq_least; STXXL_MSG("op-sequence(monotonic pq): ( push, pop, push ) * n"); for (i = 0; i < nelements; ++i) { if ((i % mega) == 0) STXXL_MSG( std::fixed << std::setprecision(2) << std::setw(5) << (100.0 * (double)i / (double)nelements) << "% " << "Inserting element " << i << " top() == " << least.key << " @ " << std::setprecision(3) << Timer.seconds() << " s" << std::setprecision(6) << std::resetiosflags(std::ios_base::floatfield)); //monotone priority queue r = least.key + rand() % modulo; sum_input += r; p.push(my_type(r)); #if SIDE_PQ side_pq.push(my_type(r)); #endif least = p.top(); sum_output += least.key; p.pop(); #if SIDE_PQ side_pq_least = side_pq.top(); side_pq.pop(); if (!(side_pq_least == least)) STXXL_MSG("Wrong result at " << i << " " << side_pq_least.key << " != " << least.key); #endif if (cmp(last_least, least)) { STXXL_MSG("Wrong order at " << i << " " << last_least.key << " > " << least.key); } else last_least = least; r = least.key + rand() % modulo; sum_input += r; p.push(my_type(r)); #if SIDE_PQ side_pq.push(my_type(r)); #endif } Timer.stop(); STXXL_MSG("Time spent for filling: " << Timer.seconds() << " s"); STXXL_MSG("Internal memory consumption of the priority queue: " << p.mem_cons() << " B"); stxxl::stats_data sd_middle(*stxxl::stats::get_instance()); std::cout << sd_middle - sd_start; Timer.reset(); Timer.start(); STXXL_MSG("op-sequence(monotonic pq): ( pop, push, pop ) * n"); for (i = 0; i < (nelements); ++i) { assert(!p.empty()); least = p.top(); sum_output += least.key; p.pop(); #if SIDE_PQ side_pq_least = side_pq.top(); side_pq.pop(); if (!(side_pq_least == least)) { STXXL_VERBOSE1("" << side_pq_least << " != " << least); } #endif if (cmp(last_least, least)) { STXXL_MSG("Wrong result at " << i << " " << last_least.key << " > " << least.key); } else last_least = least; r = least.key + rand() % modulo; sum_input += r; p.push(my_type(r)); #if SIDE_PQ side_pq.push(my_type(r)); #endif least = p.top(); sum_output += least.key; p.pop(); #if SIDE_PQ side_pq_least = side_pq.top(); side_pq.pop(); if (!(side_pq_least == least)) { STXXL_VERBOSE1("" << side_pq_least << " != " << least); } #endif if (cmp(last_least, least)) { STXXL_MSG("Wrong result at " << i << " " << last_least.key << " > " << least.key); } else last_least = least; if ((i % mega) == 0) STXXL_MSG( std::fixed << std::setprecision(2) << std::setw(5) << (100.0 * (double)i / (double)nelements) << "% " << "Popped element " << i << " == " << least.key << " @ " << std::setprecision(3) << Timer.seconds() << " s" << std::setprecision(6) << std::resetiosflags(std::ios_base::floatfield)); } STXXL_MSG("Last element " << i << " popped"); Timer.stop(); if (sum_input != sum_output) STXXL_MSG("WRONG sum! " << sum_input << " - " << sum_output << " = " << (sum_output - sum_input) << " / " << (sum_input - sum_output)); STXXL_MSG("Time spent for removing elements: " << Timer.seconds() << " s"); STXXL_MSG("Internal memory consumption of the priority queue: " << p.mem_cons() << " B"); std::cout << stxxl::stats_data(*stxxl::stats::get_instance()) - sd_middle; std::cout << *stxxl::stats::get_instance(); assert(sum_input == sum_output); }
static my_type max_value() { return my_type(std::numeric_limits<key_type>::max()); }
int main() { //![random_strong_typedef_distribution] FCPPT_MAKE_STRONG_TYPEDEF( int, my_type ); typedef fcppt::random::distribution::basic< fcppt::random::distribution::parameters::uniform_int< my_type > > distribution; //![random_strong_typedef_distribution] typedef fcppt::random::generator::minstd_rand generator_type; generator_type generator( fcppt::random::generator::seed_from_chrono< generator_type::seed >() ); typedef fcppt::random::variate< generator_type, distribution > variate; //![random_strong_typedef_variate] variate rng( generator, distribution( distribution::param_type::min( my_type( 0 ) ), distribution::param_type::max( my_type( 10 ) ) ) ); //![random_strong_typedef_variate] //![random_strong_typedef_output] for( unsigned i = 0; i < 10; ++i ) fcppt::io::cout() // Outputs objects of type my_type << rng() << FCPPT_TEXT(' '); //![random_strong_typedef_output] fcppt::io::cout() << FCPPT_TEXT('\n'); }
static my_type min_value() { return my_type((std::numeric_limits<key_type>::min)()); }