Stxxl  1.4.0
containers/leda_sm_pq_benchmark.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines