Refactor CommandQueueMT to use vararg templates
In order to make CommandQueueMT more maintainable this PR changes the previous macro hell with variadic templates instead. This makes the class far more explicit and will allow us to more easily change the way the class functions in the future. Furthermore this refactoring has allowed for some optimizations. In particular by using std::forward to delay the decision of decaying the type to as late as possible we are able to move the data from the callsite into our Command buffer and later move it to the call. In practice what this means is that compared to the old version instead of copying values 3 times, we can now get away with 1 copy, and 1 move for lvalues, and just 2 moves for rvalues. This saves quite a few operations in a hot codepath. We also now test to make sure that the amount of copies and moves are what we expect. This way we can spot performance regressions in this code easily. Somewhat unscientifically, running TPS-demo by pressing enter and not touching the controls average mspf, repeatable across many runs: before: 6.467 after : 6.202
This commit is contained in:
@ -139,7 +139,7 @@
|
||||
WRITE_ACTION \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -153,7 +153,7 @@
|
||||
virtual m_r m_type(m_arg1 p1) const override { \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -214,7 +214,7 @@
|
||||
WRITE_ACTION \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -228,7 +228,7 @@
|
||||
virtual m_r m_type(m_arg1 p1, m_arg2 p2) const override { \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -289,7 +289,7 @@
|
||||
WRITE_ACTION \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -303,7 +303,7 @@
|
||||
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -364,7 +364,7 @@
|
||||
WRITE_ACTION \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -378,7 +378,7 @@
|
||||
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -439,7 +439,7 @@
|
||||
WRITE_ACTION \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4, p5); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -453,7 +453,7 @@
|
||||
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4, p5); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -514,7 +514,7 @@
|
||||
WRITE_ACTION \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4, p5, p6); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -528,7 +528,7 @@
|
||||
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4, p5, p6); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -589,7 +589,7 @@
|
||||
WRITE_ACTION \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4, p5, p6, p7); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -603,7 +603,7 @@
|
||||
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4, p5, p6, p7); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -664,7 +664,7 @@
|
||||
WRITE_ACTION \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4, p5, p6, p7, p8); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
@ -678,7 +678,7 @@
|
||||
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \
|
||||
if (Thread::get_caller_id() != server_thread) { \
|
||||
m_r ret; \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
|
||||
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret, p1, p2, p3, p4, p5, p6, p7, p8); \
|
||||
SYNC_DEBUG \
|
||||
MAIN_THREAD_SYNC_CHECK \
|
||||
return ret; \
|
||||
|
||||
Reference in New Issue
Block a user