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_I386_H
8 #define CYCLE_I386_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
24 inline
cycles()25 cycle_type cycles()
26 {
27 cycle_type c;
28 __asm {
29 cpuid
30 rdtsc
31 mov dword ptr [c + 0], eax
32 mov dword ptr [c + 4], edx
33 }
34 return c;
35 }
36 #elif defined(__GNUC__) || \
37 defined(__INTEL_COMPILER) || defined(__ICC) || defined(_ECC) || defined(__ICL)
38 inline
cycles()39 cycle_type cycles()
40 {
41 boost::uint32_t lo, hi;
42
43 __asm__ __volatile__ (
44 "xorl %%eax, %%eax\n"
45 "cpuid\n"
46 ::: "%eax", "%ebx", "%ecx", "%edx"
47 );
48 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi) );
49 __asm__ __volatile__ (
50 "xorl %%eax, %%eax\n"
51 "cpuid\n"
52 ::: "%eax", "%ebx", "%ecx", "%edx"
53 );
54
55 return ( cycle_type)hi << 32 | lo;
56 }
57 #else
58 # error "this compiler is not supported"
59 #endif
60
61 struct cycle_overhead
62 {
operator ()cycle_overhead63 cycle_type operator()()
64 {
65 cycle_type start( cycles() );
66 return cycles() - start;
67 }
68 };
69
70 inline
overhead_cycle()71 cycle_type overhead_cycle()
72 {
73 std::size_t iterations( 10);
74 std::vector< cycle_type > overhead( iterations, 0);
75 for ( std::size_t i( 0); i < iterations; ++i)
76 std::generate(
77 overhead.begin(), overhead.end(),
78 cycle_overhead() );
79 BOOST_ASSERT( overhead.begin() != overhead.end() );
80 return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
81 }
82
83 #endif // CYCLE_I386_H
84