00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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();
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
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();
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 }