Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / context / performance / cycle_x86-64.hpp
1
2 //          Copyright Oliver Kowalke 2009.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef CYCLE_X86_64_H
8 #define CYCLE_X86_64_H
9
10 #include <algorithm>
11 #include <numeric>
12 #include <cstddef>
13 #include <vector>
14
15 #include <boost/assert.hpp>
16 #include <boost/bind.hpp>
17 #include <boost/cstdint.hpp>
18
19 #define BOOST_CONTEXT_CYCLE
20
21 typedef boost::uint64_t cycle_type;
22
23 #if _MSC_VER >= 1400
24 # include <intrin.h>
25 # pragma intrinsic(__rdtsc)
26 inline
27 cycle_type cycles()
28 { return __rdtsc(); }
29 #elif defined(__INTEL_COMPILER) || defined(__ICC) || defined(_ECC) || defined(__ICL)
30 inline
31 cycle_type cycles()
32 { return __rdtsc(); }
33 #elif defined(__GNUC__) || defined(__SUNPRO_C)
34 inline
35 cycle_type cycles()
36 {
37     boost::uint32_t lo, hi;
38
39     __asm__ __volatile__ (
40         "xorl %%eax, %%eax\n"
41         "cpuid\n"
42         ::: "%rax", "%rbx", "%rcx", "%rdx"
43     );
44     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi) );
45     __asm__ __volatile__ (
46         "xorl %%eax, %%eax\n"
47         "cpuid\n"
48         ::: "%rax", "%rbx", "%rcx", "%rdx"
49     );
50
51     return ( cycle_type)hi << 32 | lo; 
52 }
53 #else
54 # error "this compiler is not supported"
55 #endif
56
57 struct cycle_overhead
58 {
59     cycle_type operator()()
60     {
61         cycle_type start( cycles() );
62         return cycles() - start;
63     }
64 };
65
66 inline
67 cycle_type overhead_cycle()
68 {
69     std::size_t iterations( 10);
70     std::vector< cycle_type >  overhead( iterations, 0);
71     for ( std::size_t i( 0); i < iterations; ++i)
72         std::generate(
73             overhead.begin(), overhead.end(),
74             cycle_overhead() );
75     BOOST_ASSERT( overhead.begin() != overhead.end() );
76     return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
77 }
78
79 #endif // CYCLE_X86_64_H