1
1
#pragma once
2
2
3
3
#include < perfcpp/event_counter.h>
4
-
5
4
#include < iostream>
5
+ #include < fstream>
6
6
#include < mutex>
7
7
#include < vector>
8
+ #include < stdexcept>
9
+ #include < string>
8
10
9
11
namespace kmercounter {
10
- class MultithreadCounter {
12
+
13
+ class PerfCounterResult {
14
+ private:
15
+ std::vector<std::pair<std::string, double >> _results;
11
16
public:
12
- MultithreadCounter () {
13
- MultithreadCounter (1 );
17
+ PerfCounterResult (const std::vector<std::string>& events) {
18
+ for (const auto & event : events) {
19
+ _results.emplace_back (event, 0 );
20
+ }
21
+ }
22
+
23
+ void add (const perf::CounterResult& result) {
24
+ for (auto & [counter_name, counter_value] : _results) {
25
+ counter_value += result.get (counter_name).value_or (0 );
26
+ }
27
+ }
28
+
29
+ void print () {
30
+ for (auto & [counter_name, counter_value] : _results) {
31
+ std::cout << counter_name << " : " << counter_value << std::endl;
32
+ }
14
33
}
34
+ };
15
35
16
- MultithreadCounter (size_t num_threads)
17
- : num_threads(num_threads),
18
- def ()
36
+ class MultithreadCounter {
37
+ public:
38
+ // Default constructor
39
+ MultithreadCounter () {}
40
+
41
+ // Delegating constructor: reads events from a file then delegates
42
+ MultithreadCounter (size_t num_threads, const std::string& cnt_path, const std::string& def_path)
43
+ : MultithreadCounter(num_threads, readEventsFromFile(cnt_path), def_path)
19
44
{
45
+ // Nothing to do here, delegation took care of initialization.
46
+ }
47
+
48
+ // Main constructor: uses events vector
49
+ MultithreadCounter (size_t num_threads, const std::vector<std::string>& events, const std::string& def_path)
50
+ : num_threads(num_threads), events(events) {
51
+ results.reserve (num_threads);
52
+ defs.reserve (num_threads);
20
53
counters.reserve (num_threads);
21
54
for (size_t i = 0 ; i < num_threads; ++i) {
22
- counters.emplace_back (def);
55
+ results.emplace_back (this ->events );
56
+ if (def_path.empty ())
57
+ defs.emplace_back ();
58
+ else
59
+ defs.emplace_back (def_path);
60
+ counters.emplace_back (defs[i]);
61
+ counters[i].add (this ->events );
23
62
}
24
63
}
25
64
@@ -32,28 +71,44 @@ class MultithreadCounter {
32
71
void stop (size_t thread_idx) {
33
72
if (thread_idx < num_threads) {
34
73
counters[thread_idx].stop ();
74
+ results[thread_idx].add (counters[thread_idx].result ());
75
+ counters[thread_idx].close ();
35
76
}
36
77
}
37
78
38
- void add (const std::vector<std::string>& events) {
79
+ void print () {
80
+ std::cout << " \n ------- PERFCPP ------- " << std::endl;
39
81
for (size_t i = 0 ; i < num_threads; i++) {
40
- counters[i].add (events);
82
+ std::cout << " \n Thread ID: " << i << std::endl;
83
+ results[i].print ();
41
84
}
85
+ std::cout << " \n ----------------------- " << std::endl;
42
86
}
43
87
44
- void show () {
45
- for (int i = 0 ; i < num_threads; i++) {
46
- auto result = counters[i].result ();
47
- std::cout << " \n TID: " << i << " PERFCPP Results:" << std::endl;
48
- for (const auto & [counter_name, counter_value] : result) {
49
- std::cout << counter_value << " " << counter_name << std::endl;
88
+ private:
89
+ // Helper function to read events from file
90
+ static std::vector<std::string> readEventsFromFile (const std::string& path) {
91
+ std::vector<std::string> events;
92
+ if (path.empty ())
93
+ return events;
94
+
95
+ std::ifstream file (path);
96
+ if (!file.is_open ()) {
97
+ throw std::runtime_error (" Error: Unable to open file " + path);
98
+ }
99
+ std::string line;
100
+ while (std::getline (file, line)) {
101
+ if (!line.empty ()) {
102
+ events.push_back (line);
50
103
}
51
104
}
105
+ return events;
52
106
}
53
107
54
- private:
55
- std::vector<perf::EventCounter> counters ;
56
- perf::CounterDefinition def ;
108
+ std::vector<perf::EventCounter> counters; // Each counter needs its own definitions
109
+ std::vector<perf::CounterDefinition> defs ;
110
+ std::vector<PerfCounterResult> results ;
57
111
size_t num_threads;
112
+ std::vector<std::string> events;
58
113
};
59
- } // namespace kmercounter
114
+ } // namespace kmercounter
0 commit comments