Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * containers/pq_benchmark.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2006 Roman Dementiev <dementiev@ira.uka.de> 00007 * Copyright (C) 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00008 * 00009 * Distributed under the Boost Software License, Version 1.0. 00010 * (See accompanying file LICENSE_1_0.txt or copy at 00011 * http://www.boost.org/LICENSE_1_0.txt) 00012 **************************************************************************/ 00013 00014 //! \example containers/pq_benchmark.cpp 00015 //! This is a benchmark mentioned in the paper 00016 //! R. Dementiev, L. Kettner, P. Sanders "STXXL: standard template library for XXL data sets" 00017 //! Software: Practice and Experience 00018 //! Volume 38, Issue 6, Pages 589-637, May 2008 00019 //! DOI: 10.1002/spe.844 00020 00021 00022 #include <limits> 00023 #include <stxxl/priority_queue> 00024 #include <stxxl/stats> 00025 #include <stxxl/timer> 00026 00027 #define TOTAL_PQ_MEM_SIZE (768 * 1024 * 1024) 00028 00029 #define PQ_MEM_SIZE (512 * 1024 * 1024) 00030 00031 #define PREFETCH_POOL_SIZE ((TOTAL_PQ_MEM_SIZE - PQ_MEM_SIZE) / 2) 00032 #define WRITE_POOL_SIZE (PREFETCH_POOL_SIZE) 00033 00034 00035 #define MAX_ELEMENTS (2000 * 1024 * 1024) 00036 00037 00038 struct my_record 00039 { 00040 int key; 00041 int data; 00042 my_record() : key(0), data(0) { } 00043 my_record(int k, int d) : key(k), data(d) { } 00044 }; 00045 00046 std::ostream & operator << (std::ostream & o, const my_record & obj) 00047 { 00048 o << obj.key << " " << obj.data; 00049 return o; 00050 } 00051 00052 bool operator == (const my_record & a, const my_record & b) 00053 { 00054 return a.key == b.key; 00055 } 00056 00057 bool operator != (const my_record & a, const my_record & b) 00058 { 00059 return a.key != b.key; 00060 } 00061 00062 bool operator < (const my_record & a, const my_record & b) 00063 { 00064 return a.key < b.key; 00065 } 00066 00067 bool operator > (const my_record & a, const my_record & b) 00068 { 00069 return a.key > b.key; 00070 } 00071 00072 00073 struct comp_type : std::binary_function<my_record, my_record, bool> 00074 { 00075 bool operator () (const my_record & a, const my_record & b) const 00076 { 00077 return a > b; 00078 } 00079 static my_record min_value() 00080 { 00081 return my_record((std::numeric_limits<int>::max)(), 0); 00082 } 00083 }; 00084 00085 00086 typedef stxxl::PRIORITY_QUEUE_GENERATOR<my_record, comp_type, 00087 PQ_MEM_SIZE, MAX_ELEMENTS / (1024 / 8)>::result pq_type; 00088 00089 typedef pq_type::block_type block_type; 00090 00091 #define BLOCK_SIZE block_type::raw_size 00092 00093 00094 #if 1 00095 unsigned ran32State = 0xdeadbeef; 00096 inline int myrand() 00097 { 00098 return ((int)((ran32State = 1664525 * ran32State + 1013904223) >> 1)) - 1; 00099 } 00100 #else // a longer pseudo random sequence 00101 long long unsigned ran32State = 0xdeadbeef; 00102 inline long long unsigned myrand() 00103 { 00104 return (ran32State = (ran32State * 0x5DEECE66DULL + 0xBULL) & 0xFFFFFFFFFFFFULL); 00105 } 00106 #endif 00107 00108 00109 void run_stxxl_insert_all_delete_all(stxxl::uint64 ops) 00110 { 00111 pq_type PQ(PREFETCH_POOL_SIZE, WRITE_POOL_SIZE); 00112 00113 stxxl::uint64 i; 00114 00115 my_record cur; 00116 00117 stxxl::stats_data stats_begin(*stxxl::stats::get_instance()); 00118 00119 stxxl::timer Timer; 00120 Timer.start(); 00121 00122 for (i = 0; i < ops; ++i) 00123 { 00124 cur.key = myrand(); 00125 PQ.push(cur); 00126 } 00127 00128 Timer.stop(); 00129 00130 STXXL_MSG("Records in PQ: " << PQ.size()); 00131 if (i != PQ.size()) 00132 { 00133 STXXL_MSG("Size does not match"); 00134 abort(); 00135 } 00136 00137 STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) << 00138 " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); 00139 00140 std::cout << stxxl::stats_data(*stxxl::stats::get_instance()) - stats_begin; 00141 00142 //////////////////////////////////////////////// 00143 00144 stats_begin = *stxxl::stats::get_instance(); 00145 Timer.reset(); 00146 Timer.start(); 00147 00148 for (i = 0; i < ops; ++i) 00149 { 00150 PQ.pop(); 00151 } 00152 00153 Timer.stop(); 00154 00155 STXXL_MSG("Records in PQ: " << PQ.size()); 00156 if (!PQ.empty()) 00157 { 00158 STXXL_MSG("PQ must be empty"); 00159 abort(); 00160 } 00161 00162 STXXL_MSG("Deletions elapsed time: " << (Timer.mseconds() / 1000.) << 00163 " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); 00164 00165 std::cout << stxxl::stats_data(*stxxl::stats::get_instance()) - stats_begin; 00166 } 00167 00168 00169 void run_stxxl_intermixed(stxxl::uint64 ops) 00170 { 00171 pq_type PQ(PREFETCH_POOL_SIZE, WRITE_POOL_SIZE); 00172 00173 stxxl::uint64 i; 00174 00175 my_record cur; 00176 00177 stxxl::stats_data stats_begin(*stxxl::stats::get_instance()); 00178 00179 stxxl::timer Timer; 00180 Timer.start(); 00181 00182 for (i = 0; i < ops; ++i) 00183 { 00184 cur.key = myrand(); 00185 PQ.push(cur); 00186 } 00187 00188 Timer.stop(); 00189 00190 STXXL_MSG("Records in PQ: " << PQ.size()); 00191 if (i != PQ.size()) 00192 { 00193 STXXL_MSG("Size does not match"); 00194 abort(); 00195 } 00196 00197 STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) << 00198 " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); 00199 00200 std::cout << stxxl::stats_data(*stxxl::stats::get_instance()) - stats_begin; 00201 00202 //////////////////////////////////////////////// 00203 00204 stats_begin = *stxxl::stats::get_instance(); 00205 Timer.reset(); 00206 Timer.start(); 00207 00208 for (i = 0; i < ops; ++i) 00209 { 00210 int o = myrand() % 3; 00211 if (o == 0) 00212 { 00213 cur.key = myrand(); 00214 PQ.push(cur); 00215 } 00216 else 00217 { 00218 assert(!PQ.empty()); 00219 PQ.pop(); 00220 } 00221 } 00222 00223 Timer.stop(); 00224 00225 STXXL_MSG("Records in PQ: " << PQ.size()); 00226 00227 STXXL_MSG("Deletions/Insertion elapsed time: " << (Timer.mseconds() / 1000.) << 00228 " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); 00229 00230 std::cout << stxxl::stats_data(*stxxl::stats::get_instance()) - stats_begin; 00231 } 00232 00233 int main(int argc, char * argv[]) 00234 { 00235 STXXL_MSG("stxxl::pq lock size: " << BLOCK_SIZE << " bytes"); 00236 00237 #ifdef STXXL_DIRECT_IO_OFF 00238 STXXL_MSG("STXXL_DIRECT_IO_OFF is defined"); 00239 #else 00240 STXXL_MSG("STXXL_DIRECT_IO_OFF is NOT defined"); 00241 #endif 00242 00243 if (argc < 3) 00244 { 00245 STXXL_MSG("Usage: " << argv[0] << " version #ops"); 00246 STXXL_MSG("\t version = 1: insert-all-delete-all stxxl pq"); 00247 STXXL_MSG("\t version = 2: intermixed insert/delete stxxl pq"); 00248 return -1; 00249 } 00250 00251 int version = atoi(argv[1]); 00252 stxxl::int64 ops = stxxl::atoint64(argv[2]); 00253 00254 00255 STXXL_MSG("Running version : " << version); 00256 STXXL_MSG("Operations to perform: " << ops); 00257 00258 switch (version) 00259 { 00260 case 1: 00261 run_stxxl_insert_all_delete_all(ops); 00262 break; 00263 case 2: 00264 run_stxxl_intermixed(ops); 00265 break; 00266 default: 00267 STXXL_MSG("Unsupported version " << version); 00268 } 00269 }