summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/context/performance/cycle_x86-64.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/context/performance/cycle_x86-64.hpp')
-rw-r--r--src/boost/libs/context/performance/cycle_x86-64.hpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/boost/libs/context/performance/cycle_x86-64.hpp b/src/boost/libs/context/performance/cycle_x86-64.hpp
new file mode 100644
index 00000000..fae0226c
--- /dev/null
+++ b/src/boost/libs/context/performance/cycle_x86-64.hpp
@@ -0,0 +1,79 @@
+
+// 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 CYCLE_X86_64_H
+#define CYCLE_X86_64_H
+
+#include <algorithm>
+#include <numeric>
+#include <cstddef>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_CONTEXT_CYCLE
+
+typedef boost::uint64_t cycle_type;
+
+#if _MSC_VER >= 1400
+# include <intrin.h>
+# pragma intrinsic(__rdtsc)
+inline
+cycle_type cycles()
+{ return __rdtsc(); }
+#elif defined(__INTEL_COMPILER) || defined(__ICC) || defined(_ECC) || defined(__ICL)
+inline
+cycle_type cycles()
+{ return __rdtsc(); }
+#elif defined(__GNUC__) || defined(__SUNPRO_C)
+inline
+cycle_type cycles()
+{
+ boost::uint32_t lo, hi;
+
+ __asm__ __volatile__ (
+ "xorl %%eax, %%eax\n"
+ "cpuid\n"
+ ::: "%rax", "%rbx", "%rcx", "%rdx"
+ );
+ __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi) );
+ __asm__ __volatile__ (
+ "xorl %%eax, %%eax\n"
+ "cpuid\n"
+ ::: "%rax", "%rbx", "%rcx", "%rdx"
+ );
+
+ return ( cycle_type)hi << 32 | lo;
+}
+#else
+# error "this compiler is not supported"
+#endif
+
+struct cycle_overhead
+{
+ cycle_type operator()()
+ {
+ cycle_type start( cycles() );
+ return cycles() - start;
+ }
+};
+
+inline
+cycle_type overhead_cycle()
+{
+ std::size_t iterations( 10);
+ std::vector< cycle_type > overhead( iterations, 0);
+ for ( std::size_t i( 0); i < iterations; ++i)
+ std::generate(
+ overhead.begin(), overhead.end(),
+ cycle_overhead() );
+ BOOST_ASSERT( overhead.begin() != overhead.end() );
+ return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
+}
+
+#endif // CYCLE_X86_64_H