00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "SysDeps/UnitTest.h"
00033 #include "Utility/String.h"
00034
00035 #include <algorithm>
00036 #include <stdio.h>
00037
00038 #include "lib/shttl/array2d.h"
00039 #include "lib/shttl/bit.h"
00040 #include "lib/shttl/bitset.h"
00041 #include "lib/shttl/counter.h"
00042 #include "lib/shttl/counter_array.h"
00043 #include "lib/shttl/integer.h"
00044 #include "lib/shttl/lru.h"
00045 #include "lib/shttl/nlu.h"
00046
00047 #include "lib/shttl/setassoc_table.h"
00048
00049 #include "lib/shttl/double_hasher.h"
00050 #include "lib/shttl/simple_hasher.h"
00051 #include "lib/shttl/std_hasher.h"
00052 #include "lib/shttl/static_off_hasher.h"
00053
00054 using namespace shttl;
00055
00056 namespace Onikiri
00057 {
00058 ONIKIRI_TEST_CLASS(SHTTL)
00059 {
00060 public:
00061
00062 ONIKIRI_TEST_METHOD(SHTTL_BitOperations)
00063 {
00064 ONIKIRI_TEST_ARE_EQUAL( (u64)0, xor_convolute(0, 10), "XOR convolution failed." );
00065 ONIKIRI_TEST_ARE_EQUAL( (u64)1, xor_convolute(1, 10), "XOR convolution failed." );
00066 ONIKIRI_TEST_ARE_EQUAL( (u64)255, xor_convolute(255, 10), "XOR convolution failed." );
00067 ONIKIRI_TEST_ARE_EQUAL( (u64)1023, xor_convolute(1023 << 10, 10), "XOR convolution failed." );
00068 ONIKIRI_TEST_ARE_EQUAL( (u64)1022, xor_convolute((1023 << 10) | 1, 10), "XOR convolution failed." );
00069 }
00070
00071 ONIKIRI_TEST_METHOD(SHTTL_Counter)
00072 {
00073
00074 {
00075 counter<u8> c(
00076 0,
00077 0,
00078 1,
00079 1,
00080 1,
00081 1
00082 );
00083
00084 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00085 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00086
00087 ONIKIRI_TEST_IS_TRUE( c.inc() == 1, "" );
00088 ONIKIRI_TEST_IS_TRUE( c.inc() == 1, "" );
00089
00090 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00091 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00092
00093 ONIKIRI_TEST_IS_TRUE( c.inc() == 1, "" );
00094 ONIKIRI_TEST_IS_TRUE( c.inc() == 1, "" );
00095
00096 ONIKIRI_TEST_IS_TRUE( c.above_threshold() == true, "" );
00097 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00098 ONIKIRI_TEST_IS_TRUE( c.above_threshold() == false, "" );
00099 }
00100
00101
00102 {
00103 counter<u8> c(
00104 0,
00105 0,
00106 3,
00107 1,
00108 1,
00109 2
00110 );
00111
00112 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00113 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00114
00115 ONIKIRI_TEST_IS_TRUE( c.inc() == 1, "" );
00116 ONIKIRI_TEST_IS_TRUE( c.inc() == 2, "" );
00117 ONIKIRI_TEST_IS_TRUE( c.inc() == 3, "" );
00118 ONIKIRI_TEST_IS_TRUE( c.inc() == 3, "" );
00119
00120 ONIKIRI_TEST_IS_TRUE( c.dec() == 2, "" );
00121 ONIKIRI_TEST_IS_TRUE( c.dec() == 1, "" );
00122
00123 ONIKIRI_TEST_IS_TRUE( c.inc() == 2, "" );
00124 ONIKIRI_TEST_IS_TRUE( c.inc() == 3, "" );
00125
00126 ONIKIRI_TEST_IS_TRUE( c.above_threshold() == true, "" );
00127 ONIKIRI_TEST_IS_TRUE( c.dec() == 2, "" );
00128 ONIKIRI_TEST_IS_TRUE( c.above_threshold() == true, "" );
00129 ONIKIRI_TEST_IS_TRUE( c.dec() == 1, "" );
00130 ONIKIRI_TEST_IS_TRUE( c.above_threshold() == false, "" );
00131 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00132 ONIKIRI_TEST_IS_TRUE( c.above_threshold() == false, "" );
00133 ONIKIRI_TEST_IS_TRUE( c.dec() == 0, "" );
00134 ONIKIRI_TEST_IS_TRUE( c.above_threshold() == false, "" );
00135 }
00136 }
00137
00138 ONIKIRI_TEST_METHOD(SHTTL_CounterArray)
00139 {
00140
00141 {
00142 int size = 256;
00143 counter_array<u8> ca(
00144 size,
00145 0,
00146 0,
00147 3,
00148 1,
00149 1,
00150 2
00151 );
00152
00153 for( int i = 0; i < size; i++ ){
00154 ONIKIRI_TEST_IS_TRUE( ca[i].dec() == 0, "" );
00155 ONIKIRI_TEST_IS_TRUE( ca[i].dec() == 0, "" );
00156
00157 ONIKIRI_TEST_IS_TRUE( ca[i].inc() == 1, "" );
00158 ONIKIRI_TEST_IS_TRUE( ca[i].inc() == 2, "" );
00159 ONIKIRI_TEST_IS_TRUE( ca[i].inc() == 3, "" );
00160 ONIKIRI_TEST_IS_TRUE( ca[i].inc() == 3, "" );
00161
00162 ONIKIRI_TEST_IS_TRUE( ca[i].dec() == 2, "" );
00163 ONIKIRI_TEST_IS_TRUE( ca[i].dec() == 1, "" );
00164
00165 ONIKIRI_TEST_IS_TRUE( ca[i].inc() == 2, "" );
00166 ONIKIRI_TEST_IS_TRUE( ca[i].inc() == 3, "" );
00167
00168 ONIKIRI_TEST_IS_TRUE( ca[i].above_threshold() == true, "" );
00169 ONIKIRI_TEST_IS_TRUE( ca[i].dec() == 2, "" );
00170 ONIKIRI_TEST_IS_TRUE( ca[i].above_threshold() == true, "" );
00171 ONIKIRI_TEST_IS_TRUE( ca[i].dec() == 1, "" );
00172 ONIKIRI_TEST_IS_TRUE( ca[i].above_threshold() == false, "" );
00173 ONIKIRI_TEST_IS_TRUE( ca[i].dec() == 0, "" );
00174 ONIKIRI_TEST_IS_TRUE( ca[i].above_threshold() == false, "" );
00175 ONIKIRI_TEST_IS_TRUE( ca[i].dec() == 0, "" );
00176 ONIKIRI_TEST_IS_TRUE( ca[i].above_threshold() == false, "" );
00177 }
00178 }
00179 }
00180
00181 ONIKIRI_TEST_METHOD(SHTTL_LRU)
00182 {
00183 LRU_Test< lru_time<u64> > ( "'lru_time<u64>' test failed.");
00184 LRU_Test< lru_order<u64> >( "'lru_order<u64>' test failed.");
00185 LRU_Test< lru_list<u64> > ( "'lru_list<u64>' test failed.");
00186 LRU_Test< lru_time<int> > ( "'lru_time<int>' test failed.");
00187 LRU_Test< lru_order<int> >( "'lru_order<int>' test failed.");
00188 LRU_Test< lru_list<int> > ( "'lru_list<int>' test failed.");
00189 LRU_Test< lru_time<u8> > ( "'lru_time<u8>' test failed.");
00190 LRU_Test< lru_order<u8> > ( "'lru_order<u8>' test failed.");
00191 LRU_Test< lru_list<u8> > ( "'lru_list<u8>' test failed.");
00192 }
00193
00194 ONIKIRI_TEST_METHOD(SHTTL_SetAssociativeTable)
00195 {
00196
00197 SetAssocTableTest<u64>();
00198 SetAssocTableTest<int>();
00199 SetAssocTableTest<u16>();
00200
00201
00202 }
00203
00204 ONIKIRI_TEST_METHOD(SHTTL_FullAssociativeTable)
00205 {
00206
00207 {
00208 setassoc_table< std::pair<u64, u64>, std_hasher< u64 >, lru<u64> >
00209 table( std_hasher< u64 >(0, 0), 8 );
00210 TableTest( table, "Set associative table(full associative) test failed." );
00211 }
00212
00213 {
00214 setassoc_table< std::pair<u64, u64>, static_off_hasher< u64, 0 >, lru<u64> >
00215 table( static_off_hasher< u64, 0 >(0), 8 );
00216 TableTest( table, "Set associative table(full associative) test failed." );
00217 }
00218 }
00219
00220 ONIKIRI_TEST_METHOD(SHTTL_DirectMapTable)
00221 {
00222
00223 {
00224 setassoc_table< std::pair<u64, u64>, std_hasher< u64 >, lru<u64> >
00225 table( std_hasher< u64 >(5, 6), 1 );
00226 TableTest( table, "Set associative table(direct map) test failed." );
00227 }
00228
00229 {
00230 setassoc_table< std::pair<u64, u64>, static_off_hasher< u64, 6 >, lru<u64> >
00231 table( static_off_hasher< u64, 6 >(5), 1 );
00232 TableTest( table, "Set associative table(direct map) test failed." );
00233 }
00234 }
00235
00236 private:
00237
00238
00239
00240
00241 template <class KeyType>
00242 void SetAssocTableTest()
00243 {
00244 {
00245 setassoc_table< std::pair<KeyType, u64>, std_hasher< KeyType >, lru<u64> >
00246 table( std_hasher< KeyType >(5, 6), 8 );
00247 TableTest( table, "Set associative table test failed." );
00248 }
00249
00250 {
00251 setassoc_table< std::pair<KeyType, u64>, std_hasher< KeyType >, nlu<u64> >
00252 table( std_hasher< KeyType >(5, 6), 8 );
00253 TableTest( table, "Set associative table test failed." );
00254 }
00255
00256 {
00257 setassoc_table< std::pair<KeyType, u64>, static_off_hasher< KeyType, 6 >, lru<u64> >
00258 table( static_off_hasher< KeyType, 6 >(5), 8 );
00259 TableTest( table, "Set associative table test failed." );
00260 }
00261
00262 {
00263 setassoc_table< std::pair<KeyType, u64>, simple_hasher< KeyType >, lru<u64> >
00264 table( simple_hasher< KeyType >(5), 8 );
00265 TableTest( table, "Set associative table test failed." );
00266 }
00267
00268
00269 {
00270 const int ways = 8;
00271 const int setBits = 5;
00272
00273 const int magic = rand();
00274
00275 typedef
00276 setassoc_table< std::pair<KeyType, u64>, std_hasher< KeyType >, lru<u64> >
00277 TableType;
00278 TableType table( std_hasher< KeyType >(setBits, 0), ways );
00279
00280
00281 for( int i = 0; i < ways; i++ ){
00282 table.write(
00283 static_cast<KeyType>(i*table.set_num()),
00284 (size_t)magic
00285 );
00286 }
00287
00288
00289 size_t count = 0;
00290 TableType::hasher_size_type index = table.index(0);
00291 for( TableType::iterator i = table.begin_set( index ); i != table.end_set( index ); ++i ){
00292 ONIKIRI_TEST_IS_TRUE( i->value == magic, "begin_set()/end_set() test failed." );
00293 count++;
00294 }
00295 ONIKIRI_TEST_IS_TRUE( count == table.way_num(), "begin_set()/end_set() test failed." );
00296
00297 }
00298 }
00299
00300 template <class Table>
00301 void TableTest( Table& table, const char* msg )
00302 {
00303 table.clear();
00304
00305
00306
00307 for(size_t i = 0;i < table.size();i++){
00308 Table::key_type addr = rand();
00309 if(i == 0)
00310 addr = ~(Table::key_type)0;
00311 else if(i == 1)
00312 addr = 0;
00313
00314 u64 val_des;
00315 ONIKIRI_TEST_IS_TRUE( table.find( addr ) == table.end(), msg );
00316 if( table.find(addr) == table.end() ){
00317 ONIKIRI_TEST_IS_TRUE( table.read( addr, &val_des ) == table.end(), msg );
00318 }
00319 }
00320
00321
00322 for(size_t i = 0;i < table.size();i++){
00323 u64 val = rand();
00324 Table::key_type addr = rand();
00325
00326
00327 if(i == 0)
00328 addr = ~(Table::key_type)0;
00329 else if(i == 1)
00330 addr = 0;
00331
00332
00333
00334 u64 val_des;
00335 table.write( addr, val );
00336 ONIKIRI_TEST_IS_TRUE( table.read( addr, &val_des ) != table.end(), msg );
00337 ONIKIRI_TEST_IS_TRUE( val_des == val, msg );
00338 ONIKIRI_TEST_IS_TRUE( table.find( addr ) != table.end(), msg );
00339
00340
00341 for( int j = 0; j < 1024; j++ ){
00342 Table::key_type test_addr = rand();
00343 if( table.index(test_addr) != table.index( addr ) )
00344 table.write( addr, val );
00345 }
00346 ONIKIRI_TEST_IS_TRUE( table.read( addr, &val_des ) != table.end(), msg );
00347 ONIKIRI_TEST_IS_TRUE( val_des == val, msg );
00348 ONIKIRI_TEST_IS_TRUE( table.find(addr) != table.end(), msg );
00349
00350
00351 table.invalidate( addr );
00352 ONIKIRI_TEST_IS_TRUE( table.find(addr) == table.end(), msg );
00353 if( table.find(addr) != table.end() ){
00354 ONIKIRI_TEST_IS_TRUE( table.read( addr, &val_des ) == table.end(), msg );
00355 }
00356 }
00357
00358
00359 {
00360 Table::key_type addr = rand();
00361 u64 val = rand();
00362
00363 table.write( addr, val );
00364
00365 typedef typename Table::iterator iterator;
00366 for( iterator i = table.begin(); i != table.end(); ++i ){
00367 i->valid = false;
00368 }
00369
00370 ONIKIRI_TEST_IS_TRUE( table.find( addr ) == table.end(), msg );
00371
00372 typedef typename Table::const_iterator const_iterator;
00373 for( const_iterator i = table.begin(); i != table.end(); ++i ){
00374 ONIKIRI_TEST_IS_TRUE( !i->valid, msg );
00375 }
00376 }
00377 }
00378
00379
00380 template< typename lru_target >
00381 void LRU_Test( const char* msg )
00382 {
00383 const int set_num = 8;
00384 const int way_num = 8;
00385 for( int index = 0; index < set_num; index++ ){
00386 std::vector<size_t> arr( way_num );
00387 for( int way = 0; way < way_num; way++ ){
00388 arr[way] = way;
00389 }
00390
00391 do {
00392 lru_target lru_oa;
00393 lru_oa.construct( set_num, way_num );
00394 for(int i = 0; i < way_num; ++i) {
00395 lru_target::key_type key = index;
00396 lru_oa.touch( index, arr[i], key );
00397 }
00398
00399 ONIKIRI_TEST_IS_TRUE( lru_oa.target( index ) == arr[0], msg );
00400
00401
00402 } while( std::next_permutation( arr.begin(), arr.end() - 1 ) );
00403 }
00404 }
00405 };
00406
00407 }