common/log: Speed improvement for log. #17938
Conversation
|
Are there any benchmarks that show the speedup? |
Signed-off-by: Adam Kupczyk <akupczyk@redhat.com>
d3ae910 to
a059e46
Compare
|
@jcsp |
|
Seems to me like a reasonable use of thread local data to cut down on allocations. Any other opinions? @liewegas ? |
|
@tchaikov 1692886 : Failed on: "cbt - Final Pool Health Check." And additional 5 jobs were running happily for 12h before being terminated. Should I proceed to clean this problems up ? |
|
@aclamk the reason why i didn't merge your PR is that i wanted to review it before doing so. but neither did i want to to be a blocker of it. so i leave the link to the rados qa tests. because none of the failures is relevant to your PR, so i didn't add a negative review. |
|
hi @aclamk, i'm having trouble figuring out what exactly was slow about current logging, and how this change set addresses it. can you explain a bit more about what you learned from your investigation?
|
src/common/PrebufferedStreambuf.h
Outdated
| : public std::basic_streambuf<char, std::basic_string<char>::traits_type> | ||
| { | ||
| prebuffered_data* m_data; | ||
| std::ostream os; |
There was a problem hiding this comment.
it seems backwards for the streambuf to contain an ostream, instead of the other way around. why can't this stay on the stack in the dout_impl macro?
There was a problem hiding this comment.
It really seems wierd that streambuf specialization has and ostream.
I did it just to avoid specialization of ostream, just to have streambuf in it.
Reusing ostream and streambuf between logs is the gist of this change.
There was a problem hiding this comment.
got it. so the ostream and streambuf will both be thread_local and have the same lifetime 👍
src/common/PrebufferedStreambuf.h
Outdated
|
|
||
| PrebufferedStreambuf(): m_data(nullptr), os(this) {}; | ||
| ~PrebufferedStreambuf(); | ||
| static PrebufferedStreambuf* get_streambuf(prebuffered_data* data); |
There was a problem hiding this comment.
if this factory function is the only way to construct a valid PrebufferedStreambuf, the constructor and destructor should be made private
this unfortunately means that you can't ever put a PrebufferedStreambuf on the stack. so if you ever want more than one in a thread, you're stuck with dynamic allocation
There was a problem hiding this comment.
Thanks. Those should be private.
The dynamic allocation is performed once per thread, and in seldom cases when we log from inside log.
|
@cbodley |
|
ok thanks @aclamk! i ran a profiler on the unit test and saw that, without your changes, the would you object to making this a separate class though, like |
|
ping |
|
thanks @aclamk, there are a lot of stringstreams in rgw that could take advantage of it someday :) |
…usage Signed-off-by: Adam Kupczyk <akupczyk@redhat.com>
5581ced to
8e1a7ea
Compare
Signed-off-by: Adam Kupczyk <akupczyk@redhat.com>
tchaikov
left a comment
There was a problem hiding this comment.
@aclamk please see the comment at #19100 (comment). we can clean this up a little bit before merging it.
| : m_buf(buf), m_buf_len(buf_len), m_pptr(nullptr) {} | ||
|
|
||
| /// return a string copy (inefficiently) | ||
| std::string get_str() const; |
There was a problem hiding this comment.
please see https://github.com/ceph/ceph/pull/19100/files#diff-8dcb74089b1227130d768a47852508bdR48, get_str(), size() and snprintf() methods are not needed here.
|
Closing, because #19100 does it better. |
streambuf and ostream are reused as much as possible.
Signed-off-by: Adam Kupczyk akupczyk@redhat.com