Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77952 - trunk/libs/context/performance
From: oliver.kowalke_at_[hidden]
Date: 2012-04-13 14:51:27


Author: olli
Date: 2012-04-13 14:51:26 EDT (Fri, 13 Apr 2012)
New Revision: 77952
URL: http://svn.boost.org/trac/boost/changeset/77952

Log:
context: enable ucontext in performance test

Text files modified:
   trunk/libs/context/performance/performance.cpp | 79 ++++++++++++++++++++++++++++++++++-----
   trunk/libs/context/performance/performance.hpp | 33 +++++++++++-----
   2 files changed, 91 insertions(+), 21 deletions(-)

Modified: trunk/libs/context/performance/performance.cpp
==============================================================================
--- trunk/libs/context/performance/performance.cpp (original)
+++ trunk/libs/context/performance/performance.cpp 2012-04-13 14:51:26 EDT (Fri, 13 Apr 2012)
@@ -11,24 +11,78 @@
 
 #include <boost/assert.hpp>
 #include <boost/bind.hpp>
+#include <boost/config.hpp>
 #include <boost/context/all.hpp>
 #include <boost/program_options.hpp>
 
+#ifndef BOOST_WINDOWS
+#include <ucontext.h>
+#endif
+
 #include "bind_processor.hpp"
 #include "performance.hpp"
 
 namespace ctx = boost::ctx;
 namespace po = boost::program_options;
 
+#ifndef BOOST_WINDOWS
+ucontext_t uc, ucm;
+#endif
 ctx::fcontext_t fc, fcm;
 
-void fn( intptr_t param)
+#ifndef BOOST_WINDOWS
+static void f2()
+{
+ while ( true)
+ ::swapcontext( & uc, & ucm);
+}
+#endif
+
+static void f1( intptr_t)
 {
- while ( param)
+ while ( true)
         ctx::jump_fcontext( & fc, & fcm, 0);
 }
 
-void test( unsigned int iterations)
+#ifndef BOOST_WINDOWS
+unsigned int test_ucontext( unsigned int iterations)
+{
+ cycle_t total( 0);
+ cycle_t overhead( get_overhead() );
+ std::cout << "overhead for rdtsc == " << overhead << " cycles" << std::endl;
+
+ // cache warum-up
+ {
+ 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, 0);
+ swapcontext( & ucm, & uc);
+ swapcontext( & ucm, & uc);
+ }
+
+ for ( unsigned int i = 0; i < iterations; ++i)
+ {
+ cycle_t start( get_cycles() );
+ swapcontext( & ucm, & uc);
+ cycle_t diff( get_cycles() - start);
+
+ // we have two jumps and two measuremt-overheads
+ diff -= overhead; // overhead of measurement
+ diff /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ BOOST_ASSERT( diff >= 0);
+ total += diff;
+ }
+ return total/iterations;
+}
+#endif
+
+unsigned int test_fcontext( unsigned int iterations)
 {
     cycle_t total( 0);
     cycle_t overhead( get_overhead() );
@@ -38,18 +92,18 @@
     {
         ctx::stack_allocator alloc;
 
- fc.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
+ fc.fc_stack.base = alloc.allocate(ctx::default_stacksize());
         fc.fc_stack.limit =
- static_cast< char * >( fc.fc_stack.base) - ctx::minimum_stacksize();
- ctx::make_fcontext( & fc, fn, 1);
+ static_cast< char * >( fc.fc_stack.base) - ctx::default_stacksize();
+ ctx::make_fcontext( & fc, f1, 0);
         ctx::start_fcontext( & fcm, & fc);
- ctx::jump_fcontext( & fcm, & fc, 1);
+ ctx::jump_fcontext( & fcm, & fc, 0);
     }
 
     for ( unsigned int i = 0; i < iterations; ++i)
     {
         cycle_t start( get_cycles() );
- ctx::jump_fcontext( & fcm, & fc, 1);
+ ctx::jump_fcontext( & fcm, & fc, 0);
         cycle_t diff( get_cycles() - start);
 
         // we have two jumps and two measuremt-overheads
@@ -59,7 +113,7 @@
         BOOST_ASSERT( diff >= 0);
         total += diff;
     }
- std::cout << "average of " << total/iterations << " cycles per switch" << std::endl;
+ return total/iterations;
 }
 
 int main( int argc, char * argv[])
@@ -92,7 +146,12 @@
 
         bind_to_processor( 0);
 
- test( iterations);
+ unsigned int res = test_fcontext( iterations);
+ std::cout << "fcontext: average of " << res << " cycles per switch" << std::endl;
+#ifndef BOOST_WINDOWS
+ res = test_ucontext( iterations);
+ std::cout << "ucontext: average of " << res << " cycles per switch" << std::endl;
+#endif
 
         return EXIT_SUCCESS;
     }

Modified: trunk/libs/context/performance/performance.hpp
==============================================================================
--- trunk/libs/context/performance/performance.hpp (original)
+++ trunk/libs/context/performance/performance.hpp 2012-04-13 14:51:26 EDT (Fri, 13 Apr 2012)
@@ -7,17 +7,28 @@
 #ifndef PERFORMANCE_H
 #define PERFORMANCE_H
 
-// msvc/icc, i386
-#if defined(_MSC_VER) && defined(_M_IX86)
-#include "performance_msvc_i386.hpp"
-
-// gcc/icc, i386
-#elif defined(__GNUC__) && defined(__i386__)
-#include "performance_gcc_i386.hpp"
-
-// gcc/icc, x86_64
-#elif defined(__GNUC__) && defined(__x86_64__)
-#include "performance_gcc_x86-64.hpp"
+// x86_64
+// test x86_64 before i386 because icc might
+// define __i686__ for x86_64 too
+#if defined(__x86_64__) || defined(__x86_64) \
+ || defined(__amd64__) || defined(__amd64) \
+ || defined(_M_X64) || defined(_M_AMD64)
+# if defined(BOOST_WINDOWS)
+# error "this platform is not supported"
+# else
+# include "performance_gcc_x86-64.hpp"
+# endif
+// i386
+#elif defined(i386) || defined(__i386__) || defined(__i386) \
+ || defined(__i486__) || defined(__i586__) || defined(__i686__) \
+ || defined(__X86__) || defined(_X86_) || defined(__THW_INTEL__) \
+ || defined(__I86__) || defined(__INTEL__) || defined(__IA32__) \
+ || defined(_M_IX86) || defined(_I86_)
+# if defined(BOOST_WINDOWS)
+# include "performance_msvc_i386.hpp"
+# else
+# include "performance_gcc_i386.hpp"
+# endif
 
 #else
 #error "this platform is not supported"


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