Stxxl
1.4.0
|
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