/* Check cf5-opt.vim defs. VIM: let g:lcppflags="-std=c++11 -O2 -pthread" VIM: let g:wcppflags="/O2 /EHsc /DWIN32" VIM: let g:cppflags=g:Iboost VIM: let g:ldflags=g:Lboost VIM: let g:ldlibpath=g:Bboost VIM: let g:argv="" VIM-: let g:cf5output=0 */ #include #include #include #include #include typedef long long duration_type; static const size_t ce = 1024L*1024L*1024L; duration_type scan_read( char * p, const size_t c, const size_t s ) { auto b = std::chrono::high_resolution_clock::now(); int sum = 0; char * qe = p+c; for ( int n =0, ne=ce/c; n < ne; ++n ) for ( size_t i = 0; i < s; ++i ) for ( char * q = p+i; q < qe; q+=s ) sum += *q; volatile int no_optimization = sum; auto e = std::chrono::high_resolution_clock::now(); return std::chrono::nanoseconds(e-b).count(); } duration_type scan_write( char * p, const size_t c, const size_t s ) { int a = rand(); auto b = std::chrono::high_resolution_clock::now(); char * qe = p+c; for ( int n =0, ne=ce/c; n < ne; ++n ) for ( size_t i = 0; i < s; ++i ) for ( char * q = p+i; q < qe; q+=s ) *q = a; auto e = std::chrono::high_resolution_clock::now(); return std::chrono::nanoseconds(e-b).count(); } template void test_steps( F f , char * p, const size_t c, char * nm ) { f( p, c, 1 ); // First run ignore. std::cout << std::setw(10) << "steps"; std::cout << std::setw(16) << nm; std::cout << std::setw(16) << nm; std::cout << std::setw(16) << nm; std::cout << std::setw(16) << "average"; std::cout << std::setw(16) << "deviation" << std::endl; for ( size_t s = 1; s < c; s<<=1 ) { std::cout << std::setw(10) << s << std::flush; auto d1 = f( p, c, s ); std::cout << std::setw(16) << d1 << std::flush; auto d2 = f( p, c, s ); std::cout << std::setw(16) << d2 << std::flush; auto d3 = f( p, c, s ); std::cout << std::setw(16) << d3 << std::flush; auto a = (d1+d2+d3)/3; std::cout << std::setw(16) << a; auto dev = (std::abs(d1-a)+std::abs(d2-a)+std::abs(d3-a))/3; std::cout << std::setw(16) << dev << std::endl; } } void test_workingset( const size_t c ) { char * p = (char*)malloc( c ); std::cout << "Working set " << c << std::endl ; test_steps( scan_read, p, c, "read" ); test_steps( scan_write, p, c, "write" ); } int main ( void ) {try{ for ( size_t c = 4096; c <= ce; c <<=1 ) test_workingset( c ); return 0; } catch ( const std::exception& e ) { std::cerr << std::endl << "std::exception(\"" << e.what() << "\")." << std::endl; return 2; } catch ( ... ) { std::cerr << std::endl << "unknown exception." << std::endl; return 1; }}