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