-
Notifications
You must be signed in to change notification settings - Fork 145
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
Perf[BMQ,MQB]: callback construction in a reusable buffer #481
base: main
Are you sure you want to change the base?
Conversation
61e1b87
to
db16c77
Compare
db16c77
to
7b8f8b6
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.
This change looks good to me. I think main
has moved a little since this was created, so once you're able to rebase, I can do a quick second review and approve.
@pniedzielski I need to refine this a bit and put performance measures |
62cd35e
to
8b62d79
Compare
BenchmarksMac M2
Linux (amd64)
From benchmark 1, there is a ~20% speed-up on repeatedly calling a functor when using managed callback. Benchmark 2 shows that building new managed callbacks is 8-10% slower than building Benchmarks 3 & 4 show the real usage scenario in Mac benchmarks are not that interesting compared to |
4ef7577
to
6cdaa03
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.
Build 2481 of commit 6cdaa03 has completed with FAILURE
6cdaa03
to
c9e0578
Compare
/// `CallbackFunctor` type. | ||
/// TODO: replace by static_assert on C++ standard update | ||
BSLS_ASSERT_SAFE(0 == static_cast<CALLBACK_TYPE*>( | ||
reinterpret_cast<CallbackFunctor*>(0))); |
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.
Compile time error if we try to pass a template class that is not a child class for CallbackFunctor
:
/blazingmq/src/groups/mqb/mqbi/mqbi_dispatcher.h:537:31: error: static_cast from 'CallbackFunctor *' to '(anonymous namespace)::Dummy *', which are not related by inheritance, is not allowed
537 | BSLS_ASSERT_SAFE(0 == static_cast<CALLBACK_TYPE*>(
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
538 | reinterpret_cast<CallbackFunctor*>(0)));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6bdb4a6
to
8731c30
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.
Build 2489 of commit 8731c30 has completed with FAILURE
8731c30
to
abea187
Compare
private: | ||
// DATA | ||
/// Reusable buffer holding the stored callback. | ||
bsl::vector<char> d_callbackBuffer; |
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.
Note that if the object stored in this buffer is not trivially copyable, we cannot simply copy ManagedCallback
objects. For this reason I removed copy/assignment operators. There is an alternative to store this d_callbackBuffer
under a shared_ptr, but I don't want to introduce this overhead unless we have a good reason to
abea187
to
e357ec4
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.
Build 2491 of commit e357ec4 has completed with FAILURE
e357ec4
to
00f7be9
Compare
Signed-off-by: Evgeny Malygin <emalygin@bloomberg.net>
00f7be9
to
a127128
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.
Build 2495 of commit a127128 has completed with FAILURE
Changes
bsl::function
usage, replace it withbmqu::ManagedCallback
.mqbi::Dispatcher::ProcessorFunctor
, pass and execute void functors only.mqbi::Dispatcher::ProcessorHandle
usage from args and callbacks (it was not actually needed).fanout30
scenario stable throughput increased by +12.5%.Problem
Bind
withbsl::function
has too much overhead. Even if there is a small buffer optimization when binding, copying or moving a binded function tobsl::function
(mqbi::DispatcherEvent::d_callback
field) causes allocations. It happens for every confirm going to the cluster.Profiler
Before (in red - everything related to

Bind
and conversions tod_callback
):After:

This PR was tested on a priority queue, and it saves ~10% of cluster thread processing time. But it should have even greater impact on Fanout queues.
Isolated benchmark
A simple benchmark for both approaches:
Outputs:
So functor to
bsl::function
conversion has 40x overhead in this example.perf
output for this sample code: