Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * containers/leda_sm_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 * 00008 * Distributed under the Boost Software License, Version 1.0. 00009 * (See accompanying file LICENSE_1_0.txt or copy at 00010 * http://www.boost.org/LICENSE_1_0.txt) 00011 **************************************************************************/ 00012 00013 //! \example containers/leda_sm_pq_benchmark.cpp 00014 //! This is a benchmark mentioned in the paper 00015 //! R. Dementiev, L. Kettner, P. Sanders "STXXL: standard template library for XXL data sets" 00016 //! Software: Practice and Experience 00017 //! Volume 38, Issue 6, Pages 589-637, May 2008 00018 //! DOI: 10.1002/spe.844 00019 00020 00021 #include <iostream> 00022 #include <algorithm> 00023 00024 #include <LEDA-SM/ext_memory_manager.h> 00025 #include <LEDA-SM/ext_memory_manager.h> 00026 #include <LEDA-SM/block.h> 00027 #include <LEDA-SM/ext_array.h> 00028 #include <LEDA-SM/debug.h> 00029 #include <LEDA-SM/array_heap.h> 00030 #include <LEDA-SM/ext_r_heap.h> 00031 #include <LEDA-SM/buffer_tree.h> 00032 #include <LEDA/random.h> 00033 00034 #include <stxxl/types> 00035 #include <stxxl/timer> 00036 00037 #define STXXL_MSG(x) \ 00038 { std::cout << "[STXXL-MSG] " << x << std::endl << std::flush; \ 00039 } 00040 00041 00042 #define PQ_MEM_SIZE (512 * 1024 * 1024) 00043 #define MAX_ELEMENTS (2000 * 1024 * 1024) 00044 00045 00046 struct my_record 00047 { 00048 int key; 00049 int data; 00050 my_record() { } 00051 my_record(int k, int d) : key(k), data(d) { } 00052 }; 00053 00054 std::ostream & operator << (std::ostream & o, const my_record & obj) 00055 { 00056 o << obj.key << " " << obj.data; 00057 return o; 00058 } 00059 00060 bool operator == (const my_record & a, const my_record & b) 00061 { 00062 return a.key == b.key; 00063 } 00064 00065 bool operator != (const my_record & a, const my_record & b) 00066 { 00067 return a.key != b.key; 00068 } 00069 00070 bool operator < (const my_record & a, const my_record & b) 00071 { 00072 return a.key < b.key; 00073 } 00074 00075 bool operator > (const my_record & a, const my_record & b) 00076 { 00077 return a.key > b.key; 00078 } 00079 00080 int compare(const my_record & a, const my_record & b) 00081 { 00082 if (a.key != b.key) 00083 return (a.key - b.key); 00084 00085 return (a.key - b.key); 00086 } 00087 00088 00089 #define BLOCK_SIZE1 (EXT_BLK_SZ * 4) 00090 #define BLOCK_SIZE2 (DISK_BLOCK_SIZE * 4) 00091 00092 00093 #if 1 00094 unsigned ran32State = 0xdeadbeef; 00095 inline int myrand() 00096 { 00097 return ((int)((ran32State = 1664525 * ran32State + 1013904223) >> 1)) - 1; 00098 } 00099 #else // a longer pseudo random sequence 00100 long long unsigned ran32State = 0xdeadbeef; 00101 inline long long unsigned myrand() 00102 { 00103 return (ran32State = (ran32State * 0x5DEECE66DULL + 0xBULL) & 0xFFFFFFFFFFFFULL); 00104 } 00105 #endif 00106 00107 int pq_blocks; 00108 00109 void run_ledasm_insert_all_delete_all(stxxl::int64 ops) 00110 { 00111 array_heap<int, int> PQ(pq_blocks); 00112 00113 stxxl::int64 i; 00114 00115 //my_record cur; 00116 00117 00118 stxxl::timer Timer; 00119 Timer.start(); 00120 00121 for (i = 0; i < ops; ++i) 00122 { 00123 PQ.insert(myrand(), 0); 00124 } 00125 00126 Timer.stop(); 00127 00128 STXXL_MSG("Records in PQ: " << PQ.size()); 00129 if (i != PQ.size()) 00130 { 00131 STXXL_MSG("Size does not match"); 00132 abort(); 00133 } 00134 00135 STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) << 00136 " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); 00137 00138 ext_mem_mgr.print_statistics(); 00139 ext_mem_mgr.reset_statistics(); 00140 //////////////////////////////////////////////// 00141 Timer.reset(); 00142 00143 for (i = 0; i < ops; ++i) 00144 { 00145 PQ.del_min(); 00146 } 00147 00148 Timer.stop(); 00149 00150 STXXL_MSG("Records in PQ: " << PQ.size()); 00151 if (!PQ.empty()) 00152 { 00153 STXXL_MSG("PQ must be empty"); 00154 abort(); 00155 } 00156 00157 STXXL_MSG("Deletions elapsed time: " << (Timer.mseconds() / 1000.) << 00158 " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); 00159 00160 00161 ext_mem_mgr.print_statistics(); 00162 } 00163 00164 00165 void run_ledasm_intermixed(stxxl::int64 ops) 00166 { 00167 array_heap<int, int> PQ(pq_blocks); 00168 00169 stxxl::int64 i; 00170 00171 //my_record cur; 00172 00173 00174 stxxl::timer Timer; 00175 Timer.start(); 00176 00177 for (i = 0; i < ops; ++i) 00178 { 00179 PQ.insert(myrand(), 0); 00180 } 00181 00182 Timer.stop(); 00183 00184 STXXL_MSG("Records in PQ: " << PQ.size()); 00185 if (i != PQ.size()) 00186 { 00187 STXXL_MSG("Size does not match"); 00188 abort(); 00189 } 00190 00191 STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) << 00192 " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); 00193 00194 ext_mem_mgr.print_statistics(); 00195 ext_mem_mgr.reset_statistics(); 00196 //////////////////////////////////////////////// 00197 Timer.reset(); 00198 00199 for (i = 0; i < ops; ++i) 00200 { 00201 int o = myrand() % 3; 00202 if (o == 0) 00203 { 00204 PQ.insert(myrand(), 0); 00205 } 00206 else 00207 { 00208 assert(!PQ.empty()); 00209 PQ.del_min(); 00210 } 00211 } 00212 00213 Timer.stop(); 00214 00215 STXXL_MSG("Records in PQ: " << PQ.size()); 00216 00217 STXXL_MSG("Deletions/Insertion elapsed time: " << (Timer.mseconds() / 1000.) << 00218 " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); 00219 00220 00221 ext_mem_mgr.print_statistics(); 00222 } 00223 00224 int main(int argc, char * argv[]) 00225 { 00226 STXXL_MSG("block size 1: " << BLOCK_SIZE1 << " bytes"); 00227 STXXL_MSG("block size 2: " << BLOCK_SIZE2 << " bytes"); 00228 00229 00230 if (argc < 3) 00231 { 00232 STXXL_MSG("Usage: " << argv[0] << " version #ops"); 00233 STXXL_MSG("\t version = 1: insert-all-delete-all leda-sm pqueue"); 00234 STXXL_MSG("\t version = 2: insert-all-delete-all leda-sm pqueue"); 00235 return -1; 00236 } 00237 00238 int version = atoi(argv[1]); 00239 stxxl::int64 ops = atoll(argv[2]); 00240 00241 if (ops > MAX_ELEMENTS) 00242 { 00243 STXXL_MSG("#ops can not be larger than " << MAX_ELEMENTS); 00244 return 0; 00245 } 00246 00247 00248 pq_blocks = PQ_MEM_SIZE / (EXT_BLK_SZ * sizeof(GenPtr)); 00249 00250 if (pq_blocks <= 500) 00251 { 00252 std::cout << "Array heap must have > 500 blocks, current number of blocks " << 00253 pq_blocks << std::endl; 00254 return -1; 00255 } 00256 00257 00258 STXXL_MSG("Running version : " << version); 00259 STXXL_MSG("Operations to perform: " << ops); 00260 00261 switch (version) 00262 { 00263 case 1: 00264 run_ledasm_insert_all_delete_all(ops); 00265 break; 00266 case 2: 00267 run_ledasm_intermixed(ops); 00268 break; 00269 default: 00270 STXXL_MSG("Unsupported version " << version); 00271 } 00272 }