New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: make the main dout() paths faster and more maintanable #20290
Conversation
src/log/SubsystemMap.h
Outdated
// The rest. Should be as small as possible to unnecessarily not | ||
// enlarge md_config_t and spread it other elements across cache | ||
// lines. Access can be slow. | ||
std::vector<ceph_subsys_item_t> m_subsys; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to carry the size as its already known. std::unique_ptr<std::array>
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good to me.
subs.add(1, "foosys", 20, 1); | ||
subs.add(2, "bar", 20, 2); | ||
subs.add(3, "baz", 10, 3); | ||
subs.set_log_level(0, 10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduce one method for that.
The make check bot fails because of:
Apparently it rebased the PR on top of freshest |
@@ -946,7 +939,7 @@ int md_config_t::_get_val(const std::string &key, char **buf, int len) const | |||
string k(ConfFile::normalize_key_name(key)); | |||
// subsys? | |||
for (size_t o = 0; o < subsys.get_num(); o++) { | |||
std::string as_option = "debug_" + subsys.get_name(o); | |||
std::string as_option = std::string("debug_") + subsys.get_name(o); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, possibly this could be made at compile-time.
src/common/config.cc
Outdated
@@ -178,13 +178,6 @@ void md_config_t::validate_schema() | |||
|
|||
void md_config_t::init_subsys() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop this.
src/common/dout.h
Outdated
} \ | ||
}(cct); \ | ||
\ | ||
if (should_gather) { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unlikely()
? I can see that GCC arranges some dout
usages in a way not friendly for static branch prediction.
src/log/SubsystemMap.h
Outdated
@@ -52,16 +66,38 @@ class SubsystemMap { | |||
return m_subsys[subsys].gather_level; | |||
} | |||
|
|||
const std::string& get_name(unsigned subsys) const { | |||
// TODO(rzarzynski): move to string_view? | |||
const char* get_name(unsigned subsys) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constexpr
.
src/log/SubsystemMap.h
Outdated
class SubsystemMap { | ||
std::vector<Subsystem> m_subsys; | ||
unsigned m_max_name_len; | ||
// Access the current gathering levels must be *FAST* as they are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FIXME: Access to
.
7cc9c41
to
a8de819
Compare
src/common/dout.h
Outdated
}(cct); \ | ||
\ | ||
if (unlikely(should_gather)) { \ | ||
[&]() __attribute__((noinline,cold)) { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be controversial as we're using compiler-specific extensions here. However, the befit seems to outweigh the costs. Please take a look on a comparison of KernelDevice::read()
translation before and after the change.
TODO: comment the intention behind the lambda and noinline,cold
.
TODO: introduce a macro-based abstraction?
src/common/dout.h
Outdated
} \ | ||
}(cct); \ | ||
\ | ||
if (unlikely(should_gather)) { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could differentiate the hinting policy basing on e.g. v
and the default gathering level. Though, I'm not sure it's really necessary.
// generic macros | ||
#define dout_prefix *_dout | ||
|
||
#define dout_impl(cct, sub, v) \ | ||
do { \ | ||
if (cct->_conf->subsys.should_gather(sub, v)) { \ | ||
const bool should_gather = [&](const auto cctX) { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting. I had an idea for replacing the template with a function accepting a lambda at one point but this is a very nice way of moving things to compile time.
#define SUBSYS(name, log, gather) \ | ||
ceph_subsys_##name, | ||
#define DEFAULT_SUBSYS(log, gather) | ||
#include "common/subsys.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it makes sense to keep this Magic Macro stuff instead of just open-coding a data structure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the idea behind subsys.h
and the macros is to have subsystems and their log/levels defined only once - a single source of true that is transformed to dependent structures later. Maybe it's possible to perform that via constexpr
functions instead of macros but I haven't investigated that.
src/common/subsys_types.h
Outdated
struct ceph_subsys_item_t { | ||
const char* name; | ||
uint8_t log_level; | ||
uint8_t gather_level; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use uint_fast8_t here, letting the compiler pick another width if it's faster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this might be a good measure to explicitly distinguish the hot path than the comment we have around m_gather_levels
. Something targeting more the human's attention than machines. Fom x86's perspective I don't expect any difference. The open questions are: 1) the effect of fast types on ARMs and 2) the proliferation of uint_fast8_t
across the codebase. This would be the first occurrence (not counting 3rd party code).
src/log/SubsystemMap.h
Outdated
// The rest. Should be as small as possible to unnecessarily not | ||
// enlarge md_config_t and spread it other elements across cache | ||
// lines. Access can be slow. | ||
std::vector<ceph_subsys_item_t> m_subsys; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good to me.
8e746c6
to
00a2614
Compare
Rebased to freshest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i will take a closer look early tomorrow.
src/common/dout.h
Outdated
@@ -43,14 +43,47 @@ class DoutPrefixProvider { | |||
virtual ~DoutPrefixProvider() {} | |||
}; | |||
|
|||
// helpers | |||
namespace ceph { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, we could do
namespace ceph::dout {
// ...
}
in C++17.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! Thanks for pointing out this feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FIXED.
src/common/subsys_types.h
Outdated
/* | ||
* Ceph - scalable distributed file system | ||
* | ||
* Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the copyright line should be updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FIXED.
00a2614
to
4411cac
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm in general.
@@ -1618,10 +1618,11 @@ bool BlueStore::OnodeSpace::map_any(std::function<bool(OnodeRef)> f) | |||
return false; | |||
} | |||
|
|||
void BlueStore::OnodeSpace::dump(CephContext *cct, int lvl) | |||
template <int LogLevelV = 30> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rzarzynski could you rebase your change against master, as 8471cb4#diff-a9faffcf40600fd57aea5451cef5abe9R6344 in #19843 was merged recently. and your PR changes the function signature of BlueStore::_dump_onode()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
676139a
to
360f823
Compare
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
The idea is to: 1. Do not put the dout()'s crafting stuff on the hot, fall-through path. Cheapest branches are those that are forward and never taken. 2. Move it to separated sections placed far away from the main path to be more friendly to ICache and ITLB. That is, dout_impl constructs a function now. Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Summary
subsys
parameter fordout
& company becomes compile-time in almost all cases. The few exceptions are explicitly requested viaceph::dout::need_dynamic
.level
compile-time validation is back and doesn't depend on the VLA extension anymore. It's performed in all cases except those explicitly requested withceph::dout::need_dynamic
.SubsystemMap::should_gather()
is gone. That is, thestd::vector
-typedm_subsys
is no longer dereferenced on the main path.SubsystemMap::should_gather<>()
requires one third of comparisons than before.Interface changes:
debug_*
configurables don't accept negative values anymore --dout()
with level-1
or0
will be always gathered. Our documentation doesn't say a word about negatives.Todo
uint8_t
fordout
levels.-1
in compile-time if possible.::should_gather()
calls to the template variant when possible.dout
's levels where possible.Performance impact
Environment
1 physial incerta node, 3 OSDs, all NVMe, Xeon E5-2650 v3
Results
0/0
.