Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78548 - trunk/libs/context/performance
From: oliver.kowalke_at_[hidden]
Date: 2012-05-23 04:17:29


Author: olli
Date: 2012-05-23 04:17:24 EDT (Wed, 23 May 2012)
New Revision: 78548
URL: http://svn.boost.org/trac/boost/changeset/78548

Log:
context: clock_gettime() added to performance measurement

Added:
   trunk/libs/context/performance/zeit.hpp (contents, props changed)
Text files modified:
   trunk/libs/context/performance/cycle_i386.hpp | 8 +-
   trunk/libs/context/performance/cycle_x86-64.hpp | 10 +-
   trunk/libs/context/performance/performance.cpp | 117 ++++++++++++++++++++++++++++++++++++---
   3 files changed, 115 insertions(+), 20 deletions(-)

Modified: trunk/libs/context/performance/cycle_i386.hpp
==============================================================================
--- trunk/libs/context/performance/cycle_i386.hpp (original)
+++ trunk/libs/context/performance/cycle_i386.hpp 2012-05-23 04:17:24 EDT (Wed, 23 May 2012)
@@ -49,14 +49,14 @@
         "cpuid\n"
         ::: "%eax", "%ebx", "%ecx", "%edx"
     );
-
+
     return ( cycle_t)hi << 32 | lo;
 }
 #else
 # error "this compiler is not supported"
 #endif
 
-struct measure
+struct measure_cycles
 {
     cycle_t operator()()
     {
@@ -66,14 +66,14 @@
 };
 
 inline
-cycle_t overhead()
+cycle_t overhead_cycles()
 {
     std::size_t iterations( 10);
     std::vector< cycle_t > overhead( iterations, 0);
     for ( std::size_t i( 0); i < iterations; ++i)
         std::generate(
             overhead.begin(), overhead.end(),
- measure() );
+ measure_cycles() );
     BOOST_ASSERT( overhead.begin() != overhead.end() );
     return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
 }

Modified: trunk/libs/context/performance/cycle_x86-64.hpp
==============================================================================
--- trunk/libs/context/performance/cycle_x86-64.hpp (original)
+++ trunk/libs/context/performance/cycle_x86-64.hpp 2012-05-23 04:17:24 EDT (Wed, 23 May 2012)
@@ -33,7 +33,7 @@
 cycle_t cycles()
 {
     boost::uint32_t lo, hi;
-
+
     __asm__ __volatile__ (
         "xorl %%eax, %%eax\n"
         "cpuid\n"
@@ -45,14 +45,14 @@
         "cpuid\n"
         ::: "%rax", "%rbx", "%rcx", "%rdx"
     );
-
+
     return ( cycle_t)hi << 32 | lo;
 }
 #else
 # error "this compiler is not supported"
 #endif
 
-struct measure
+struct measure_cycles
 {
     cycle_t operator()()
     {
@@ -62,14 +62,14 @@
 };
 
 inline
-cycle_t overhead()
+cycle_t overhead_cycles()
 {
     std::size_t iterations( 10);
     std::vector< cycle_t > overhead( iterations, 0);
     for ( std::size_t i( 0); i < iterations; ++i)
         std::generate(
             overhead.begin(), overhead.end(),
- measure() );
+ measure_cycles() );
     BOOST_ASSERT( overhead.begin() != overhead.end() );
     return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
 }

Modified: trunk/libs/context/performance/performance.cpp
==============================================================================
--- trunk/libs/context/performance/performance.cpp (original)
+++ trunk/libs/context/performance/performance.cpp 2012-05-23 04:17:24 EDT (Wed, 23 May 2012)
@@ -26,6 +26,10 @@
 #include "bind_processor.hpp"
 #include "cycle.hpp"
 
+#if _POSIX_C_SOURCE >= 199309L
+#include "zeit.hpp"
+#endif
+
 namespace ctx = boost::ctx;
 namespace po = boost::program_options;
 
@@ -62,7 +66,7 @@
         ctx::jump_fcontext( & fc, & fcm, 7, preserve_fpu);
 }
 
-cycle_t test_function( cycle_t ov)
+cycle_t test_function_cycle( cycle_t ov)
 {
     boost::function< void() > fn( boost::bind( f3) );
     // cache warum-up
@@ -81,7 +85,7 @@
 }
 
 #ifndef BOOST_WINDOWS
-cycle_t test_ucontext( cycle_t ov)
+cycle_t test_ucontext_cycle( cycle_t ov)
 {
     ctx::stack_allocator alloc;
 
@@ -108,7 +112,7 @@
 }
 #endif
 
-cycle_t test_fcontext( cycle_t ov)
+cycle_t test_fcontext_cycle( cycle_t ov)
 {
     ctx::stack_allocator alloc;
     fc.fc_stack.base = alloc.allocate(ctx::default_stacksize());
@@ -133,6 +137,79 @@
     return total;
 }
 
+#if _POSIX_C_SOURCE >= 199309L
+zeit_t test_function_zeit( zeit_t ov)
+{
+ boost::function< void() > fn( boost::bind( f3) );
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~)
+
+ zeit_t start( zeit() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~)
+ zeit_t total( zeit() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+
+#ifndef BOOST_WINDOWS
+zeit_t test_ucontext_zeit( zeit_t ov)
+{
+ ctx::stack_allocator alloc;
+
+ ::getcontext( & uc);
+ uc.uc_stack.ss_sp =
+ static_cast< char * >( alloc.allocate(ctx::default_stacksize() ) )
+ - ctx::default_stacksize();
+ uc.uc_stack.ss_size = ctx::default_stacksize();
+ ::makecontext( & uc, f2, 7);
+
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~)
+
+ zeit_t start( zeit() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~)
+ zeit_t total( zeit() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+#endif
+
+zeit_t test_fcontext_zeit( zeit_t ov)
+{
+ ctx::stack_allocator alloc;
+ fc.fc_stack.base = alloc.allocate(ctx::default_stacksize());
+ fc.fc_stack.limit =
+ static_cast< char * >( fc.fc_stack.base) - ctx::default_stacksize();
+ ctx::make_fcontext( & fc, f1);
+
+ ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
+
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
+
+ zeit_t start( zeit() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
+ zeit_t total( zeit() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+#endif
+
 int main( int argc, char * argv[])
 {
     try
@@ -158,17 +235,35 @@
         }
         bind_to_processor( 0);
 
- cycle_t ov( overhead() );
- std::cout << "overhead for rdtsc == " << ov << " cycles" << std::endl;
+ {
+ cycle_t ov( overhead_cycles() );
+ std::cout << "overhead for rdtsc == " << ov << " cycles" << std::endl;
 
- unsigned int res = test_fcontext( ov);
- std::cout << "fcontext: average of " << res << " cycles per switch" << std::endl;
+ unsigned int res = test_fcontext_cycle( ov);
+ std::cout << "fcontext: average of " << res << " cycles per switch" << std::endl;
 #ifndef BOOST_WINDOWS
- res = test_ucontext( ov);
- std::cout << "ucontext: average of " << res << " cycles per switch" << std::endl;
+ res = test_ucontext_cycle( ov);
+ std::cout << "ucontext: average of " << res << " cycles per switch" << std::endl;
+#endif
+ res = test_function_cycle( ov);
+ std::cout << "boost::function: average of " << res << " cycles per switch" << std::endl;
+ }
+
+#if _POSIX_C_SOURCE >= 199309L
+ {
+ zeit_t ov( overhead_zeit() );
+ std::cout << "\noverhead for clock_gettime() == " << ov << " ns" << std::endl;
+
+ unsigned int res = test_fcontext_zeit( ov);
+ std::cout << "fcontext: average of " << res << " ns per switch" << std::endl;
+#ifndef BOOST_WINDOWS
+ res = test_ucontext_zeit( ov);
+ std::cout << "ucontext: average of " << res << " ns per switch" << std::endl;
+#endif
+ res = test_function_zeit( ov);
+ std::cout << "boost::function: average of " << res << " ns per switch" << std::endl;
+ }
 #endif
- res = test_function( ov);
- std::cout << "boost::function: average of " << res << " cycles per switch" << std::endl;
 
         return EXIT_SUCCESS;
     }

Added: trunk/libs/context/performance/zeit.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/context/performance/zeit.hpp 2012-05-23 04:17:24 EDT (Wed, 23 May 2012)
@@ -0,0 +1,53 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef ZEIT_H
+#define ZEIT_H
+
+#include <time.h>
+
+#include <algorithm>
+#include <numeric>
+#include <cstddef>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+
+typedef boost::uint64_t zeit_t;
+
+inline
+zeit_t zeit()
+{
+ timespec t;
+ ::clock_gettime( CLOCK_PROCESS_CPUTIME_ID, & t);
+ return t.tv_sec * 1000000000 + t.tv_nsec;
+}
+
+struct measure_zeit
+{
+ zeit_t operator()()
+ {
+ zeit_t start( zeit() );
+ return zeit() - start;
+ }
+};
+
+inline
+zeit_t overhead_zeit()
+{
+ std::size_t iterations( 10);
+ std::vector< zeit_t > overhead( iterations, 0);
+ for ( std::size_t i( 0); i < iterations; ++i)
+ std::generate(
+ overhead.begin(), overhead.end(),
+ measure_zeit() );
+ BOOST_ASSERT( overhead.begin() != overhead.end() );
+ return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
+}
+
+#endif // ZEIT_H


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk