src/UnitTests/shttl.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
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             // 1bit counter
00074             {
00075                 counter<u8> c( 
00076                     0, // init
00077                     0, // min
00078                     1, // max
00079                     1, // add
00080                     1, // sub
00081                     1  // threshold
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             // 2bit counter
00102             {
00103                 counter<u8> c( 
00104                     0, // init
00105                     0, // min
00106                     3, // max
00107                     1, // add
00108                     1, // sub
00109                     2  // threshold
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             // 2bit counter array
00141             {
00142                 int size = 256;
00143                 counter_array<u8> ca(
00144                     size, // size
00145                     0, // init
00146                     0, // min
00147                     3, // max
00148                     1, // add
00149                     1, // sub
00150                     2  // threshold
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             // u64, int and u16 are key types.
00197             SetAssocTableTest<u64>();
00198             SetAssocTableTest<int>();
00199             SetAssocTableTest<u16>();
00200             // <u8> cannot pass the test because there is not enough address 
00201             // space.
00202         }
00203 
00204         ONIKIRI_TEST_METHOD(SHTTL_FullAssociativeTable)
00205         {
00206             // index:0 (full associative), offset:0
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             // way:1 (direct map)
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         // --- setassoc_table test ---
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             // Iterator set test
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                 // Write a magic number to all lines in the first set.
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                 // Check whether a magic number is written to the lines.
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             // Read from a cleared table.
00306             // Results must be always miss.
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             // write test
00322             for(size_t i = 0;i < table.size();i++){
00323                 u64 val  = rand();
00324                 Table::key_type addr = rand();
00325 
00326                 // special address test
00327                 if(i == 0)
00328                     addr = ~(Table::key_type)0;
00329                 else if(i == 1)
00330                     addr = 0;
00331 
00332 
00333                 // single write test
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                 // multiple write test
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                 // invalidate test
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             // iterator test
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         // LRU algorithm test
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                     // Check if a first touched index is next replace target();
00399                     ONIKIRI_TEST_IS_TRUE( lru_oa.target( index ) == arr[0], msg );
00400 
00401                 // Check all combinations.
00402                 } while( std::next_permutation( arr.begin(), arr.end() - 1 ) );
00403             }
00404         }
00405     };
00406 
00407 }

Onikiri2に対してTue Jun 18 14:34:26 2013に生成されました。  doxygen 1.4.7