cycle_x86-64.hpp 1.8 KB

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