$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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"