Stxxl  1.4.0
mng/test_block_scheduler.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  containers/test_block_scheduler.cpp
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2010-2011 Raoul Steffen <R-Steffen@gmx.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 #include <stxxl/bits/mng/block_scheduler.h>
00014 
00015 // Thanks Daniel Russel, Stanford University
00016 #include <Argument_helper.h>
00017 
00018 #include <iostream>
00019 #include <limits>
00020 
00021 using namespace stxxl;
00022 
00023 template <class IBT>
00024 void set_pattern_A(IBT & ib)
00025 {
00026     for (int_type i = 0; i < ib.size; ++i)
00027         ib[i] = i;
00028 }
00029 
00030 template <class IBT>
00031 int_type test_pattern_A(IBT & ib)
00032 {
00033     int_type num_err = 0;
00034     for (int_type i = 0; i < ib.size; ++i)
00035         num_err += (ib[i] != i);
00036     return num_err;
00037 }
00038 
00039 template <class IBT>
00040 void set_pattern_B(IBT & ib)
00041 {
00042     for (int_type i = 0; i < ib.size; ++i)
00043         ib[i] = ib.size - i;
00044 }
00045 
00046 template <class IBT>
00047 int_type test_pattern_B(IBT & ib)
00048 {
00049     int_type num_err = 0;
00050     for (int_type i = 0; i < ib.size; ++i)
00051         num_err += (ib[i] != ib.size - i);
00052     return num_err;
00053 }
00054 
00055 int main(int argc, char **argv)
00056 {
00057     const int block_size = 1024;
00058     typedef int_type value_type;
00059 
00060     int test_case = -1;
00061     int internal_memory_megabytes = 256;
00062 
00063     dsr::Argument_helper ah;
00064     ah.new_named_int('t', "test-case", "I", "number of the test case to run", test_case);
00065     ah.new_named_int('m', "memory", "N", "internal memory to use (in megabytes)", internal_memory_megabytes);
00066     ah.set_description("stxxl block_scheduler test");
00067     ah.set_author("Raoul Steffen, R-Steffen@gmx.de");
00068     ah.process(argc, argv);
00069 
00070     int_type internal_memory = int_type(internal_memory_megabytes) * 1048576;
00071 
00072     typedef block_scheduler< swappable_block<value_type, block_size> > bst;
00073     typedef bst::swappable_block_identifier_type sbit;
00074     typedef bst::internal_block_type ibt;
00075     typedef bst::external_block_type ebt;
00076 
00077     switch (test_case)
00078     {
00079     case -1:
00080     case 0:
00081         {   // ------------------- call all functions -----------------------
00082             STXXL_MSG("next test: call all functions");
00083             ebt ext_bl; // prepare an external_block with pattern A
00084             block_manager::get_instance()->new_block(striping(), ext_bl);
00085             ibt * int_bl = new ibt;
00086             set_pattern_A(*int_bl);
00087             int_bl->write(ext_bl)->wait();
00088 
00089             bst * b_s = new bst(internal_memory); // the block_scheduler may use internal_memory byte for caching
00090             bst & bs = *b_s;
00091             assert(! bs.is_simulating()); // make sure is not just recording a prediction sequence
00092 
00093             sbit sbi1 = bs.allocate_swappable_block(); // allocate a swappable_block and store its identifier
00094             if (bs.is_initialized(sbi1)) // it should not be initialized
00095                     STXXL_ERRMSG("new block is initialized");
00096             bs.initialize(sbi1, ext_bl); // initialize the swappable_block with the prepared external_block
00097             {
00098                 ibt & ib = bs.acquire(sbi1); // acquire the swappable_block to gain access
00099                 int_type num_err = 0;
00100                 for (int_type i = 0; i < block_size; ++i)
00101                     num_err += (ib[i] != i); // read from the swappable_block. it should contain pattern A
00102                 if (num_err)
00103                     STXXL_ERRMSG("previously initialized block had " << num_err << " errors.");
00104             }
00105             {
00106                 ibt & ib = bs.get_internal_block(sbi1); // get a new reference to the already allocated block (because we forgot the old one)
00107                 for (int_type i = 0; i < block_size; ++i)
00108                     ib[i] = block_size - i; // write pattern B
00109                 bs.release(sbi1, true); // release the swappable_block. changes have to be stored. it may now be swapped out.
00110             }
00111             sbit sbi2 = bs.allocate_swappable_block(); // allocate a second swappable_block and store its identifier
00112             if (bs.is_initialized(sbi2)) // it should not be initialized
00113                 STXXL_ERRMSG("new block is initialized");
00114             {
00115                 ibt & ib1 = bs.acquire(sbi1); // acquire the swappable_block to gain access
00116                 ibt & ib2 = bs.acquire(sbi2); // acquire the swappable_block to gain access because it was uninitialized, it now becomes initialized
00117                 for (int_type i = 0; i < block_size; ++i)
00118                     ib2[i] = ib1[i]; // copy pattern B
00119                 bs.release(sbi1, false); // release the swappable_block. no changes happened.
00120                 bs.release(sbi2, true);
00121             }
00122             if (! bs.is_initialized(sbi1)) // both blocks should now be initialized
00123                     STXXL_ERRMSG("block is not initialized");
00124             if (! bs.is_initialized(sbi2)) // both blocks should now be initialized
00125                         STXXL_ERRMSG("block is not initialized");
00126             ext_bl = bs.extract_external_block(sbi2); // get the external_block
00127             if (bs.is_initialized(sbi2)) // should not be initialized any more
00128                 STXXL_ERRMSG("block is initialized after extraction");
00129             bs.deinitialize(sbi1);
00130             if (bs.is_initialized(sbi1)) // should not be initialized any more
00131                 STXXL_ERRMSG("block is initialized after deinitialize");
00132             bs.free_swappable_block(sbi1); // free the swappable_blocks
00133             bs.free_swappable_block(sbi2);
00134             bs.explicit_timestep();
00135 
00136             block_scheduler_algorithm_simulation< swappable_block<value_type, block_size> > * asim =
00137                     new block_scheduler_algorithm_simulation< swappable_block<value_type, block_size> >(bs);
00138             delete bs.switch_algorithm_to(asim);
00139             sbit sbi = bs.allocate_swappable_block();
00140             bs.acquire(sbi);
00141             bs.acquire(sbi);
00142             bs.release(sbi,true);
00143             bs.explicit_timestep();
00144             bs.release(sbi,false);
00145             bs.deinitialize(sbi);
00146             bs.initialize(sbi, ebt());
00147             if (bs.is_simulating())
00148                 bs.extract_external_block(sbi);
00149             else
00150                 bs.extract_external_block(sbi);
00151             bs.free_swappable_block(sbi);
00152             if (true)
00153             {
00154                 bst::prediction_sequence_type ps = bs.get_prediction_sequence();
00155                 for (bst::prediction_sequence_type::iterator it = ps.begin(); it != ps.end(); ++it)
00156                     STXXL_MSG("id: " << it->id << " op: " << it->op << " t: " << it->time);
00157             }
00158 
00159             delete bs.switch_algorithm_to(new
00160                     block_scheduler_algorithm_offline_lfd< swappable_block<value_type, block_size> >(asim));
00161             sbi = bs.allocate_swappable_block();
00162             bs.acquire(sbi);
00163             bs.acquire(sbi);
00164             bs.release(sbi,true);
00165             bs.explicit_timestep();
00166             bs.release(sbi,false);
00167             bs.deinitialize(sbi);
00168             bs.initialize(sbi, ebt());
00169             if (bs.is_simulating())
00170                 bs.extract_external_block(sbi);
00171             else
00172                 bs.extract_external_block(sbi);
00173             bs.free_swappable_block(sbi);
00174 
00175             delete bs.switch_algorithm_to(new
00176                     block_scheduler_algorithm_offline_lru_prefetching< swappable_block<value_type, block_size> >(asim));
00177             sbi = bs.allocate_swappable_block();
00178             bs.acquire(sbi);
00179             bs.acquire(sbi);
00180             bs.release(sbi,true);
00181             bs.explicit_timestep();
00182             bs.release(sbi,false);
00183             bs.deinitialize(sbi);
00184             bs.initialize(sbi, ebt());
00185             if (bs.is_simulating())
00186                 bs.extract_external_block(sbi);
00187             else
00188                 bs.extract_external_block(sbi);
00189             bs.free_swappable_block(sbi);
00190 
00191             delete b_s;
00192 
00193             int_bl->read(ext_bl)->wait();
00194             int_type num_err = test_pattern_B(*int_bl); // check the block. it should contain pattern B.
00195             if (num_err)
00196                 STXXL_ERRMSG("after extraction changed block had " << num_err << " errors.");
00197             delete int_bl;
00198         }
00199         {   // ---------- force swapping ---------------------
00200             STXXL_MSG("next test: force swapping");
00201             const int_type num_sb = 5;
00202 
00203             bst * b_s = new bst(block_size * sizeof(value_type) * 3); // only 3 internal_blocks allowed
00204             sbit sbi[num_sb];
00205             for (int_type i = 0; i < num_sb; ++i)
00206                 sbi[i] = b_s->allocate_swappable_block();
00207             ibt * ib[num_sb];
00208             ib[0] = &b_s->acquire(sbi[0]); // fill 3 blocks
00209             ib[1] = &b_s->acquire(sbi[1]);
00210             ib[2] = &b_s->acquire(sbi[2]);
00211             set_pattern_A(*ib[0]);
00212             set_pattern_A(*ib[1]);
00213             set_pattern_A(*ib[2]);
00214             b_s->release(sbi[0], true);
00215             b_s->release(sbi[1], true);
00216             b_s->release(sbi[2], true);
00217 
00218             ib[3] = &b_s->acquire(sbi[3]); // fill 2 blocks, now some others have to be swapped out
00219             ib[4] = &b_s->acquire(sbi[4]);
00220             set_pattern_A(*ib[3]);
00221             set_pattern_A(*ib[4]);
00222             b_s->release(sbi[3], true);
00223             b_s->release(sbi[4], true);
00224 
00225             ib[2] = &b_s->acquire(sbi[2]); // this block can still be cached
00226             ib[3] = &b_s->acquire(sbi[3]); // as can this
00227             ib[1] = &b_s->acquire(sbi[1]); // but not this
00228             if (test_pattern_A(*ib[1]))
00229                 STXXL_ERRMSG("Block 1 had errors.");
00230             if (test_pattern_A(*ib[2]))
00231                 STXXL_ERRMSG("Block 2 had errors.");
00232             if (test_pattern_A(*ib[3]))
00233                 STXXL_ERRMSG("Block 3 had errors.");
00234             b_s->release(sbi[1], false);
00235             b_s->release(sbi[2], false);
00236             b_s->release(sbi[3], false);
00237             for (int_type i = 0; i < num_sb; ++i)
00238                 b_s->free_swappable_block(sbi[i]);
00239             delete b_s;
00240         }
00241         break;
00242     case 1:
00243         {   // ---------- do not free uninitialized block ---------------------
00244             STXXL_MSG("next test: do not free uninitialized block");
00245 
00246             bst * b_s = new bst(block_size * sizeof(value_type));
00247             sbit sbi;
00248 
00249             sbi = b_s->allocate_swappable_block();
00250             b_s->acquire(sbi);
00251             b_s->release(sbi, false);
00252             // do not free uninitialized block
00253 
00254             delete b_s;
00255         }
00256         break;
00257     case 2:
00258         {   // ---------- do not free initialized block ---------------------
00259             STXXL_MSG("next test: do not free initialized block");
00260 
00261             bst * b_s = new bst(block_size * sizeof(value_type));
00262             sbit sbi;
00263 
00264             sbi = b_s->allocate_swappable_block();
00265             b_s->acquire(sbi);
00266             b_s->release(sbi, true);
00267             // do not free initialized block
00268 
00269             delete b_s;
00270         }
00271         break;
00272     case 3:
00273         {   // ---------- do not release but free block ---------------------
00274             STXXL_MSG("next test: do not release but free block");
00275 
00276             bst * b_s = new bst(block_size * sizeof(value_type));
00277             sbit sbi;
00278 
00279             sbi = b_s->allocate_swappable_block();
00280             b_s->acquire(sbi);
00281             // do not release block
00282             b_s->free_swappable_block(sbi);
00283 
00284             delete b_s;
00285         }
00286         break;
00287     case 4:
00288         {   // ---------- do neither release nor free block ---------------------
00289             STXXL_MSG("next test: do neither release nor free block");
00290 
00291             bst * b_s = new bst(block_size * sizeof(value_type));
00292             sbit sbi;
00293 
00294             sbi = b_s->allocate_swappable_block();
00295             b_s->acquire(sbi);
00296             // do not release block
00297             // do not free block
00298 
00299             delete b_s;
00300         }
00301         break;
00302     case 5:
00303         {   // ---------- release block to often ---------------------
00304             STXXL_MSG("next test: release block to often");
00305 
00306             bst * b_s = new bst(block_size * sizeof(value_type));
00307             sbit sbi;
00308 
00309             sbi = b_s->allocate_swappable_block();
00310             b_s->acquire(sbi);
00311             b_s->release(sbi, false);
00312             b_s->release(sbi, false); // release once to often
00313 
00314             delete b_s;
00315         }
00316         break;
00317     }
00318     STXXL_MSG("end of test");
00319     return 0;
00320 }
00321 
00322 
00323 
00324 
00325 
00326 
00327 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines