Skip to content

Commit 48cecbb

Browse files
authored
some performance optimisations (#135)
* allow a try_region_[begin|end] for performance improfments
1 parent c2f2f0e commit 48cecbb

3 files changed

Lines changed: 90 additions & 38 deletions

File tree

src/scorepy/cInstrumenter.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,31 +115,39 @@ bool CInstrumenter::on_event(PyFrameObject& frame, int what, PyObject*)
115115
case PyTrace_CALL:
116116
{
117117
const PyCodeObject& code = *frame.f_code;
118-
const char* name = PyUnicode_AsUTF8(code.co_name);
119-
const char* module_name = get_module_name(frame);
120-
assert(name);
121-
assert(module_name);
122-
// TODO: Use string_view/CString comparison?
123-
if (std::string(name) != "_unsetprofile" && std::string(module_name, 0, 6) != "scorep")
118+
bool success = try_region_begin(reinterpret_cast<std::uintptr_t>(&code));
119+
if (!success)
124120
{
125-
const int line_number = code.co_firstlineno;
126-
const auto file_name = get_file_name(frame);
127-
region_begin(name, module_name, file_name, line_number,
128-
reinterpret_cast<std::uintptr_t>(&code));
121+
const char* name = PyUnicode_AsUTF8(code.co_name);
122+
const char* module_name = get_module_name(frame);
123+
assert(name);
124+
assert(module_name);
125+
// TODO: Use string_view/CString comparison?
126+
if (std::string(name) != "_unsetprofile" && std::string(module_name, 0, 6) != "scorep")
127+
{
128+
const int line_number = code.co_firstlineno;
129+
const std::string file_name = get_file_name(frame);
130+
region_begin(name, module_name, file_name, line_number,
131+
reinterpret_cast<std::uintptr_t>(&code));
132+
}
129133
}
130134
break;
131135
}
132136
case PyTrace_RETURN:
133137
{
134138
const PyCodeObject& code = *frame.f_code;
135-
const char* name = PyUnicode_AsUTF8(code.co_name);
136-
const char* module_name = get_module_name(frame);
137-
assert(name);
138-
assert(module_name);
139-
// TODO: Use string_view/CString comparison?
140-
if (std::string(name) != "_unsetprofile" && std::string(module_name, 0, 6) != "scorep")
139+
bool success = try_region_end(reinterpret_cast<std::uintptr_t>(&code));
140+
if (!success)
141141
{
142-
region_end(name, module_name, reinterpret_cast<std::uintptr_t>(&code));
142+
const char* name = PyUnicode_AsUTF8(code.co_name);
143+
const char* module_name = get_module_name(frame);
144+
assert(name);
145+
assert(module_name);
146+
// TODO: Use string_view/CString comparison?
147+
if (std::string(name) != "_unsetprofile" && std::string(module_name, 0, 6) != "scorep")
148+
{
149+
region_end(name, module_name, reinterpret_cast<std::uintptr_t>(&code));
150+
}
143151
}
144152
break;
145153
}

src/scorepy/events.cpp

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,16 @@
1-
#include "events.hpp"
2-
#include <Python.h>
31
#include <algorithm>
42
#include <array>
53
#include <iostream>
6-
#include <scorep/SCOREP_User_Functions.h>
7-
#include <scorep/SCOREP_User_Variables.h>
8-
#include <unordered_map>
94

10-
namespace scorepy
11-
{
5+
#include <Python.h>
126

13-
struct region_handle
14-
{
15-
constexpr region_handle() = default;
16-
~region_handle() = default;
17-
constexpr bool operator==(const region_handle& other)
18-
{
19-
return this->value == other.value;
20-
}
21-
SCOREP_User_RegionHandle value = SCOREP_USER_INVALID_REGION;
22-
};
7+
#include "events.hpp"
8+
#include "pythonHelpers.hpp"
239

24-
constexpr region_handle uninitialised_region_handle = region_handle();
10+
namespace scorepy
11+
{
2512

26-
static std::unordered_map<std::uintptr_t, region_handle> regions;
13+
std::unordered_map<std::uintptr_t, region_handle> regions;
2714
static std::unordered_map<std::string, region_handle> user_regions;
2815
static std::unordered_map<std::string, region_handle> rewind_regions;
2916

src/scorepy/events.hpp

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
11
#pragma once
2-
32
#include <cstdint>
43
#include <string>
4+
#include <unordered_map>
5+
6+
#include <scorep/SCOREP_User_Functions.h>
7+
#include <scorep/SCOREP_User_Variables.h>
58

69
namespace scorepy
710
{
11+
12+
struct region_handle
13+
{
14+
constexpr region_handle() = default;
15+
~region_handle() = default;
16+
constexpr bool operator==(const region_handle& other)
17+
{
18+
return this->value == other.value;
19+
}
20+
constexpr bool operator!=(const region_handle& other)
21+
{
22+
return this->value != other.value;
23+
}
24+
25+
SCOREP_User_RegionHandle value = SCOREP_USER_INVALID_REGION;
26+
};
27+
28+
constexpr region_handle uninitialised_region_handle = region_handle();
29+
830
/// Combine the arguments into a region name
931
/// Return value is a statically allocated string to avoid memory (re)allocations
1032
inline const std::string& make_region_name(const std::string& module_name, const std::string& name)
@@ -16,12 +38,48 @@ inline const std::string& make_region_name(const std::string& module_name, const
1638
return region;
1739
}
1840

41+
extern std::unordered_map<std::uintptr_t, region_handle> regions;
42+
43+
/** tries to enter a region. Return true on success
44+
*
45+
*/
46+
inline bool try_region_begin(std::uintptr_t identifier)
47+
{
48+
auto it = regions.find(identifier);
49+
if (it != regions.end())
50+
{
51+
SCOREP_User_RegionEnter(it->second.value);
52+
return true;
53+
}
54+
else
55+
{
56+
return false;
57+
}
58+
}
59+
1960
void region_begin(const std::string& function_name, const std::string& module,
2061
const std::string& file_name, const std::uint64_t line_number,
2162
const std::uintptr_t& identifier);
2263
void region_begin(const std::string& function_name, const std::string& module,
2364
const std::string& file_name, const std::uint64_t line_number);
2465

66+
/** tries to end a region. Return true on success
67+
*
68+
*/
69+
inline bool try_region_end(std::uintptr_t identifier)
70+
{
71+
auto it_region = regions.find(identifier);
72+
if (it_region != regions.end())
73+
{
74+
SCOREP_User_RegionEnd(it_region->second.value);
75+
return true;
76+
}
77+
else
78+
{
79+
return false;
80+
}
81+
}
82+
2583
void region_end(const std::string& function_name, const std::string& module,
2684
const std::uintptr_t& identifier);
2785
void region_end(const std::string& function_name, const std::string& module);
@@ -34,5 +92,4 @@ void rewind_end(std::string region_name, bool value);
3492
void parameter_int(std::string name, int64_t value);
3593
void parameter_uint(std::string name, uint64_t value);
3694
void parameter_string(std::string name, std::string value);
37-
3895
} // namespace scorepy

0 commit comments

Comments
 (0)