#include <iostream>
#include <vector>
#include <cstdlib>
#include <sys/time.h>
#include <unistd.h>
template < int x, int y>
struct ArrayDim1 {
int array[ x* y] ;
int read( int nx, int ny ) {
return array[ ( ny* x) + nx] ;
}
void write( int nx, int ny, int val ) {
array[ ( ny* x) + nx] = val;
}
} ;
template < int x, int y>
struct ArrayDim2 {
int array[ y] [ x] ;
int read( int nx, int ny ) {
return array[ ny] [ nx] ;
}
void write( int nx, int ny, int val ) {
array[ ny] [ nx] = val;
}
} ;
template < class Type>
void seqRead( Type& a, int mx, int my) {
volatile int temp;
for ( int i = 0 ; i < my; i++ ) {
for ( int j = 0 ; j < mx; j++ ) {
temp = a.read ( i,j) ;
}
}
}
template < class Type>
void seqWrite( Type& a, int mx, int my) {
for ( int i = 0 ; i < my; i++ ) {
for ( int j = 0 ; j < mx; j++ ) {
a.write ( i,j,i* j) ;
}
}
}
struct Point {
int x;
int y;
Point( ) { }
Point( int nx,int ny) : x( nx) , y( ny) { }
} ;
template < class Type>
void randRead( Type& a, std:: vector < Point> & addrs) {
std:: vector < Point> :: iterator it;
volatile int temp;
Point p;
for ( it = addrs.begin ( ) ; it ! = addrs.end ( ) ; it++ ) {
p = * it;
temp = a.read ( p.x ,p.y ) ;
}
}
template < class Type>
void randWrite( Type& a, std:: vector < Point> & addrs) {
std:: vector < Point> :: iterator it;
Point p;
for ( it = addrs.begin ( ) ; it ! = addrs.end ( ) ; it++ ) {
p = * it;
a.write ( p.x ,p.y ,p.x + p.y ) ;
}
}
std:: vector < Point> randGen( int mx, int my) {
std:: vector < Point> seq;
std:: vector < Point> r;
for ( int y = 0 ; y < my; y++ ) {
for ( int x = 0 ; x < mx; x++ ) {
seq.push_back ( Point( x,y) ) ;
}
}
while ( seq.size ( ) > 0 ) {
int n = std:: rand ( ) % seq.size ( ) ;
r.push_back ( seq[ n] ) ;
seq.erase ( seq.begin ( ) + n ) ;
}
return r;
}
template < int x, int y>
struct ArrayTest {
typedef ArrayDim1< x,y> dim1;
typedef ArrayDim2< x,y> dim2;
typedef std:: vector < Point> Ps;
enum {
value_x = x,
value_y = y
} ;
dim1 a1;
dim2 a2;
Ps rnd;
ArrayTest( ) {
this- > rnd = randGen( x,y) ;
seqWrite( a1,x,y) ;
seqWrite( a2,x,y) ;
}
void testSeqR1( ) { seqRead( a1,x,y) ; }
void testSeqR2( ) { seqRead( a2,x,y) ; }
void testSeqW1( ) { seqWrite( a1,x,y) ; }
void testSeqW2( ) { seqWrite( a2,x,y) ; }
void testRndR1( ) { randRead( a1,rnd) ; }
void testRndR2( ) { randRead( a2,rnd) ; }
void testRndW1( ) { randWrite( a1,rnd) ; }
void testRndW2( ) { randWrite( a2,rnd) ; }
} ;
long getUSec( ) {
timeval tm ;
gettimeofday( & tm , NULL ) ;
return ( tm .tv_sec * 1000 * 1000 ) + tm .tv_usec ;
}
#define do_test_loop(c,x,y) \
{ \
long st = getUSec(); \
cout << (y); \
for( int i_loop_ct = 0; i_loop_ct < (x); i_loop_ct++ ){\
c; \
} \
cout << (getUSec() - st) << endl; \
}
int main( ) {
using namespace std;
typedef ArrayTest< 256 ,256 > AT;
cout << "begin initialize test object with Array " <<
AT:: value_x << "*" << AT:: value_y
<< " (" <<
( ( AT:: value_x * AT:: value_y * sizeof ( int ) ) / 1024 )
<< " KiB)" << endl;
cout .flush ( ) ;
AT* testMem = new AT( ) ;
AT& test = * testMem;
cout << "... done" << endl;
cout << "[time unit: micro-sec]" << endl;
do_test_loop( test.testSeqR1 ( ) , 1000 ,
"sequential read x 1000: array[x*y] ... " ) ;
do_test_loop( test.testSeqW1 ( ) , 1000 ,
"sequential write x 1000: array[x*y] ... " ) ;
do_test_loop( test.testRndR1 ( ) , 1000 ,
"random read x 1000: array[x*y] ... " ) ;
do_test_loop( test.testRndW1 ( ) , 1000 ,
"random write x 1000: array[x*y] ... " ) ;
do_test_loop( test.testSeqR2 ( ) , 1000 ,
"sequential read x 1000: array[y][x] ... " ) ;
do_test_loop( test.testSeqW2 ( ) , 1000 ,
"sequential write x 1000: array[y][x] ... " ) ;
do_test_loop( test.testRndR2 ( ) , 1000 ,
"random read x 1000: array[y][x] ... " ) ;
do_test_loop( test.testRndW2 ( ) , 1000 ,
"random write x 1000: array[y][x] ... " ) ;
return 0 ;
}
CgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxjc3RkbGliPgoKI2luY2x1ZGUgPHN5cy90aW1lLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KCnRlbXBsYXRlIDxpbnQgeCwgaW50IHk+CnN0cnVjdCBBcnJheURpbTEgewogICAgaW50IGFycmF5W3gqeV07CgogICAgaW50IHJlYWQoaW50IG54LCBpbnQgbnkgKXsKICAgICAgICByZXR1cm4gYXJyYXlbKG55KngpK254XTsKICAgIH0KCiAgICB2b2lkIHdyaXRlKGludCBueCwgaW50IG55LCBpbnQgdmFsICl7CiAgICAgICAgYXJyYXlbKG55KngpK254XSA9IHZhbDsKICAgIH0KfTsKCnRlbXBsYXRlIDxpbnQgeCwgaW50IHk+CnN0cnVjdCBBcnJheURpbTIgewogICAgaW50IGFycmF5W3ldW3hdOwoKICAgIGludCByZWFkKGludCBueCwgaW50IG55ICl7CiAgICAgICAgcmV0dXJuIGFycmF5W255XVtueF07CiAgICB9CgogICAgdm9pZCB3cml0ZShpbnQgbngsIGludCBueSwgaW50IHZhbCApewogICAgICAgIGFycmF5W255XVtueF0gPSB2YWw7CiAgICB9Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBUeXBlPgp2b2lkIHNlcVJlYWQoVHlwZSYgYSwgaW50IG14LCBpbnQgbXkpewogICAgdm9sYXRpbGUgaW50IHRlbXA7CiAgICBmb3IoIGludCBpID0gMDsgaSA8IG15OyBpKysgKXsKICAgICAgICBmb3IoIGludCBqID0gMDsgaiA8IG14OyBqKysgKXsKICAgICAgICAgICAgdGVtcCA9IGEucmVhZChpLGopOwogICAgICAgIH0KICAgIH0KfQoKdGVtcGxhdGU8Y2xhc3MgVHlwZT4Kdm9pZCBzZXFXcml0ZShUeXBlJiBhLCBpbnQgbXgsIGludCBteSl7CiAgICBmb3IoIGludCBpID0gMDsgaSA8IG15OyBpKysgKXsKICAgICAgICBmb3IoIGludCBqID0gMDsgaiA8IG14OyBqKysgKXsKICAgICAgICAgICAgYS53cml0ZShpLGosaSpqKTsKICAgICAgICB9CiAgICB9Cn0KCnN0cnVjdCBQb2ludCB7CiAgICBpbnQgeDsKICAgIGludCB5OwogICAgUG9pbnQoKXt9CiAgICBQb2ludChpbnQgbngsaW50IG55KTogeChueCksIHkobnkpIHt9Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBUeXBlPgp2b2lkIHJhbmRSZWFkKFR5cGUmIGEsIHN0ZDo6dmVjdG9yPFBvaW50PiYgYWRkcnMpewogICAgc3RkOjp2ZWN0b3I8UG9pbnQ+OjppdGVyYXRvciBpdDsKICAgIHZvbGF0aWxlIGludCB0ZW1wOwoKICAgIFBvaW50IHA7CiAgICBmb3IoIGl0ID0gYWRkcnMuYmVnaW4oKTsgaXQgIT0gYWRkcnMuZW5kKCk7IGl0KysgKXsKICAgICAgICBwID0gKml0OwogICAgICAgIHRlbXAgPSBhLnJlYWQocC54LHAueSk7CiAgICB9Cn0KCnRlbXBsYXRlPGNsYXNzIFR5cGU+CnZvaWQgcmFuZFdyaXRlKFR5cGUmIGEsIHN0ZDo6dmVjdG9yPFBvaW50PiYgYWRkcnMpewogICAgc3RkOjp2ZWN0b3I8UG9pbnQ+OjppdGVyYXRvciBpdDsKICAgIFBvaW50IHA7CiAgICBmb3IoIGl0ID0gYWRkcnMuYmVnaW4oKTsgaXQgIT0gYWRkcnMuZW5kKCk7IGl0KysgKXsKICAgICAgICBwID0gKml0OwogICAgICAgIGEud3JpdGUocC54LHAueSxwLngrcC55KTsKICAgIH0KfQoKCnN0ZDo6dmVjdG9yPFBvaW50PiByYW5kR2VuKGludCBteCwgaW50IG15KXsKICAgIHN0ZDo6dmVjdG9yPFBvaW50PiBzZXE7CiAgICBzdGQ6OnZlY3RvcjxQb2ludD4gcjsKCiAgICBmb3IoIGludCB5ID0gMDsgeSA8IG15OyB5KysgKXsKICAgICAgICBmb3IoIGludCB4ID0gMDsgeCA8IG14OyB4KysgKXsKICAgICAgICAgICAgc2VxLnB1c2hfYmFjayhQb2ludCh4LHkpKTsKICAgICAgICB9CiAgICB9CiAgICB3aGlsZSggc2VxLnNpemUoKSA+IDAgKXsKICAgICAgICBpbnQgbiA9IHN0ZDo6cmFuZCgpICUgc2VxLnNpemUoKTsKICAgICAgICByLnB1c2hfYmFjayggc2VxW25dICk7CiAgICAgICAgc2VxLmVyYXNlKCBzZXEuYmVnaW4oKSArIG4gKTsKICAgIH0KICAgIHJldHVybiByOwp9CgoKdGVtcGxhdGUgPGludCB4LCBpbnQgeT4Kc3RydWN0IEFycmF5VGVzdCB7CiAgICB0eXBlZGVmIEFycmF5RGltMTx4LHk+IGRpbTE7CiAgICB0eXBlZGVmIEFycmF5RGltMjx4LHk+IGRpbTI7CiAgICB0eXBlZGVmIHN0ZDo6dmVjdG9yPFBvaW50PiBQczsKCiAgICBlbnVtIHsKICAgICAgICB2YWx1ZV94ID0geCwKICAgICAgICB2YWx1ZV95ID0geQogICAgfTsKCiAgICBkaW0xIGExOwogICAgZGltMiBhMjsKICAgIFBzIHJuZDsKCiAgICBBcnJheVRlc3QoKXsKICAgICAgICB0aGlzLT5ybmQgPSByYW5kR2VuKHgseSk7CiAgICAgICAgc2VxV3JpdGUoYTEseCx5KTsKICAgICAgICBzZXFXcml0ZShhMix4LHkpOwogICAgfQoKICAgIHZvaWQgdGVzdFNlcVIxKCl7IHNlcVJlYWQoYTEseCx5KTsgfQogICAgdm9pZCB0ZXN0U2VxUjIoKXsgc2VxUmVhZChhMix4LHkpOyB9CiAgICB2b2lkIHRlc3RTZXFXMSgpeyBzZXFXcml0ZShhMSx4LHkpOyB9CiAgICB2b2lkIHRlc3RTZXFXMigpeyBzZXFXcml0ZShhMix4LHkpOyB9CiAgICB2b2lkIHRlc3RSbmRSMSgpeyByYW5kUmVhZChhMSxybmQpOyB9CiAgICB2b2lkIHRlc3RSbmRSMigpeyByYW5kUmVhZChhMixybmQpOyB9CiAgICB2b2lkIHRlc3RSbmRXMSgpeyByYW5kV3JpdGUoYTEscm5kKTsgfQogICAgdm9pZCB0ZXN0Um5kVzIoKXsgcmFuZFdyaXRlKGEyLHJuZCk7IH0KfTsKCgoKbG9uZyBnZXRVU2VjKCl7CiAgICB0aW1ldmFsIHRtOwogICAgZ2V0dGltZW9mZGF5KCZ0bSwgTlVMTCk7CgogICAgcmV0dXJuICh0bS50dl9zZWMgKiAxMDAwKjEwMDApICsgdG0udHZfdXNlYzsKfQoKI2RlZmluZSBkb190ZXN0X2xvb3AoYyx4LHkpIFwKICAgIHsgXAogICAgICAgIGxvbmcgc3QgPSBnZXRVU2VjKCk7IFwKICAgICAgICBjb3V0IDw8ICAoeSk7IFwKICAgICAgICBmb3IoIGludCBpX2xvb3BfY3QgPSAwOyBpX2xvb3BfY3QgPCAoeCk7IGlfbG9vcF9jdCsrICl7XAogICAgICAgICAgICBjOyBcCiAgICAgICAgfSBcCiAgICAgICAgY291dCA8PCAoZ2V0VVNlYygpIC0gc3QpIDw8IGVuZGw7IFwKICAgIH0KCmludCBtYWluKCl7CiAgICB1c2luZyBuYW1lc3BhY2Ugc3RkOwoKICAgIHR5cGVkZWYgQXJyYXlUZXN0PDI1NiwyNTY+IEFUOwoKICAgIGNvdXQgPDwgICJiZWdpbiBpbml0aWFsaXplIHRlc3Qgb2JqZWN0IHdpdGggQXJyYXkgIiA8PAoJICAgICAgICBBVDo6dmFsdWVfeCA8PCAiKiIgPDwgQVQ6OnZhbHVlX3kKICAgICAgICAgPDwgIiAoIiA8PAogICAgICAgICAJKChBVDo6dmFsdWVfeCAqIEFUOjp2YWx1ZV95ICogc2l6ZW9mKGludCkpIC8gMTAyNCkKICAgICAgICAgPDwgIiBLaUIpIjw8IGVuZGw7CiAgICAgICAgIAoKICAgIGNvdXQuZmx1c2goKTsKCiAgICBBVCogdGVzdE1lbSA9IG5ldyBBVCgpOwoKICAgIEFUJiB0ZXN0ID0gKnRlc3RNZW07CgoKICAgIGNvdXQgPDwgICIuLi4gZG9uZSIgPDwgZW5kbDsKCiAgICBjb3V0IDw8ICAiW3RpbWUgdW5pdDogbWljcm8tc2VjXSIgPDwgZW5kbDsKICAgIGRvX3Rlc3RfbG9vcCggdGVzdC50ZXN0U2VxUjEoKSwgMTAwMCwKICAgICAgICAic2VxdWVudGlhbCByZWFkICB4IDEwMDA6IGFycmF5W3gqeV0gIC4uLiAiICk7CgogICAgZG9fdGVzdF9sb29wKCB0ZXN0LnRlc3RTZXFXMSgpLCAxMDAwLAogICAgICAgICJzZXF1ZW50aWFsIHdyaXRlIHggMTAwMDogYXJyYXlbeCp5XSAgLi4uICIgKTsKCiAgICBkb190ZXN0X2xvb3AoIHRlc3QudGVzdFJuZFIxKCksIDEwMDAsCiAgICAgICAgInJhbmRvbSAgICAgcmVhZCAgeCAxMDAwOiBhcnJheVt4KnldICAuLi4gIiApOwoKICAgIGRvX3Rlc3RfbG9vcCggdGVzdC50ZXN0Um5kVzEoKSwgMTAwMCwKICAgICAgICAicmFuZG9tICAgICB3cml0ZSB4IDEwMDA6IGFycmF5W3gqeV0gIC4uLiAiICk7CgoKCiAgICBkb190ZXN0X2xvb3AoIHRlc3QudGVzdFNlcVIyKCksIDEwMDAsCiAgICAgICAgInNlcXVlbnRpYWwgcmVhZCAgeCAxMDAwOiBhcnJheVt5XVt4XSAuLi4gIiApOwoKICAgIGRvX3Rlc3RfbG9vcCggdGVzdC50ZXN0U2VxVzIoKSwgMTAwMCwKICAgICAgICAic2VxdWVudGlhbCB3cml0ZSB4IDEwMDA6IGFycmF5W3ldW3hdIC4uLiAiICk7CgogICAgZG9fdGVzdF9sb29wKCB0ZXN0LnRlc3RSbmRSMigpLCAxMDAwLAogICAgICAgICJyYW5kb20gICAgIHJlYWQgIHggMTAwMDogYXJyYXlbeV1beF0gLi4uICIgKTsKCiAgICBkb190ZXN0X2xvb3AoIHRlc3QudGVzdFJuZFcyKCksIDEwMDAsCiAgICAgICAgInJhbmRvbSAgICAgd3JpdGUgeCAxMDAwOiBhcnJheVt5XVt4XSAuLi4gIiApOwoKICAgIHJldHVybiAwOwp9Cg==