Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
PerfCounterMng.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7
8#ifndef ARCANE_PERFCOUNTERMNG_H_
9#define ARCANE_PERFCOUNTERMNG_H_
10
11//GG: This whole part is very Linux/x64 specific and shouldn't be here:
12// put everything that is specific into PlatformUtils
13#ifdef ARCANE_OS_LINUX
14
15#include <string>
16#include <vector>
17#include <iostream>
18#include <iomanip>
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23//#define ACTIVATE_PERF_COUNTER
24#ifdef ACTIVATE_PERF_COUNTER
25#define CHECKPERF(instruction) (instruction);
26#else
27#define CHECKPERF(instruction)
28#endif
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39#if defined(__x86_64__)
40#ifndef WIN32
41static inline void rdtsc(volatile unsigned long long int* counter)
42{
43
44 asm volatile("rdtsc \n\t"
45 "movl %%eax,%0 \n\t"
46 "movl %%edx,%1 \n\t"
47 : "=m"(((unsigned*)counter)[0]), "=m"(((unsigned*)counter)[1])
48 :
49 : "eax", "edx");
50}
51
52#define RDTSC(X) asm volatile("rdtsc \n\t" \
53 "movl %%eax,%0 \n\t" \
54 "movl %%edx,%1 \n\t" \
55 : "=m"(((unsigned*)(X))[0]), "=m"(((unsigned*)(X))[1]) \
56 : \
57 : "eax", "edx")
58#else
59
60#include <intrin.h>
61#pragma intrinsic(__rdtsc)
62
63static inline void rdtsc(volatile unsigned long long int* counter)
64{
65 *counter = __rdtsc();
66}
67
68#define RDTSC(X) *X = __rdtsc()
69
70#endif // WIN32
71
72#else // defined(__x86_64__)
73
74// NO-OP IMPLEMENTATION: To be deleted with this file.
75static inline void rdtsc(volatile unsigned long long int* counter)
76{
77 *counter = 1;
78}
79
80#endif // defined(__x86_64__)
81
82//! Returns the CPU frequency in MHz
83extern "C++" int arcaneGetCpuBaseFrequency();
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88template <typename PerfCounterT>
89class PerfCounterMng
90{
91 public:
92
93 typedef unsigned long long int ValueType;
94 typedef typename PerfCounterT::eType PhaseType;
95 typedef std::pair<ValueType, ValueType> CountType;
96 typedef std::vector<CountType> CountListType;
97
98 PerfCounterMng()
99 : m_last_value(0)
100 {
101 m_cpu_frec = arcaneGetCpuBaseFrequency();
102 m_counts.resize(PerfCounterT::NbCounters);
103 init();
104 }
105
106 virtual ~PerfCounterMng() {}
107
108 void init()
109 {
110 for (std::size_t i = 0; i < m_counts.size(); ++i) {
111 m_counts[i].first = 0;
112 m_counts[i].second = 0;
113 }
114 }
115
116 void init(PhaseType const& phase)
117 {
118 CountType& count = m_counts[phase];
119 count.first = 0;
120 count.second = 0;
121 }
122 void start(PhaseType const& phase)
123 {
124 rdtsc(&m_counts[phase].second);
125 }
126 void stop(PhaseType const& phase)
127 {
128 CountType& count = m_counts[phase];
129 rdtsc(&m_last_value);
130 m_last_value = m_last_value - count.second;
131 count.first += m_last_value;
132 }
133
134 ValueType getLastValue()
135 {
136 return m_last_value;
137 }
138
139 ValueType getValue(PhaseType const& phase)
140 {
141 return m_counts[phase].first;
142 }
143
144 double getValueInSeconds(PhaseType const& phase)
145 {
146 return m_counts[phase].first / m_cpu_frec * 1E-6;
147 }
148
149 void printInfo() const
150 {
151 std::cout << "PERF INFO : " << std::endl;
152 std::cout << std::setw(10) << "COUNT" << " : " << "VALUE" << std::endl;
153 //for(typename CountListType::const_iterator iter = m_counts.begin();iter!=m_counts.end();++iter)
154 for (std::size_t i = 0; i < m_counts.size(); ++i) {
155 std::cout << std::setw(10) << PerfCounterT::m_names[i] << " : " << m_counts[i].first / m_cpu_frec * 1E-6 << '\n';
156 }
157 }
158
159 void printInfo(std::ostream& stream) const
160 {
161 stream << "PERF INFO : " << std::endl;
162 stream << std::setw(10) << "COUNT" << " : " << "VALUE" << std::endl;
163 //for(typename CountListType::const_iterator iter = m_counts.begin();iter!=m_counts.end();++iter)
164 for (std::size_t i = 0; i < m_counts.size(); ++i) {
165 stream << std::setw(10) << PerfCounterT::m_names[i] << " : " << m_counts[i].first / m_cpu_frec * 1E-6 << '\n';
166 }
167 }
168
169 private:
170
171 ValueType m_last_value;
172 CountListType m_counts;
173 double m_cpu_frec;
174};
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
179} // namespace Arcane
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
184#else // ARCANE_OS_LINUX
185
186#define CHECKPERF(instruction)
187
188#endif // ARCANE_OS_LINUX
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
193#endif
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
int arcaneGetCpuBaseFrequency()
Returns the CPU frequency in MHz.