Merge pull request #40078 from Algunenano/threadlocal_perf

Optimize CurrentMemoryTracker alloc and free
This commit is contained in:
Maksim Kita 2022-08-12 10:24:54 +02:00 committed by GitHub
commit e2ae0d585b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 13 deletions

View File

@ -23,6 +23,7 @@ if (COMPILER_CLANG)
no_warning(zero-length-array) no_warning(zero-length-array)
no_warning(c++98-compat-pedantic) no_warning(c++98-compat-pedantic)
no_warning(c++98-compat) no_warning(c++98-compat)
no_warning(c++20-compat) # Use constinit in C++20 without warnings
no_warning(conversion) no_warning(conversion)
no_warning(ctad-maybe-unsupported) # clang 9+, linux-only no_warning(ctad-maybe-unsupported) # clang 9+, linux-only
no_warning(disabled-macro-expansion) no_warning(disabled-macro-expansion)

View File

@ -43,13 +43,6 @@ ProfileEvents::Counters & CurrentThread::getProfileEvents()
return current_thread ? current_thread->performance_counters : ProfileEvents::global_counters; return current_thread ? current_thread->performance_counters : ProfileEvents::global_counters;
} }
MemoryTracker * CurrentThread::getMemoryTracker()
{
if (unlikely(!current_thread))
return nullptr;
return &current_thread->memory_tracker;
}
void CurrentThread::updateProgressIn(const Progress & value) void CurrentThread::updateProgressIn(const Progress & value)
{ {
if (unlikely(!current_thread)) if (unlikely(!current_thread))

View File

@ -54,7 +54,12 @@ public:
static void updatePerformanceCounters(); static void updatePerformanceCounters();
static ProfileEvents::Counters & getProfileEvents(); static ProfileEvents::Counters & getProfileEvents();
static MemoryTracker * getMemoryTracker(); inline ALWAYS_INLINE static MemoryTracker * getMemoryTracker()
{
if (unlikely(!current_thread))
return nullptr;
return &current_thread->memory_tracker;
}
/// Update read and write rows (bytes) statistics (used in system.query_thread_log) /// Update read and write rows (bytes) statistics (used in system.query_thread_log)
static void updateProgressIn(const Progress & value); static void updateProgressIn(const Progress & value);

View File

@ -24,9 +24,7 @@ namespace ErrorCodes
extern const int LOGICAL_ERROR; extern const int LOGICAL_ERROR;
} }
thread_local ThreadStatus constinit * current_thread = nullptr;
thread_local ThreadStatus * current_thread = nullptr;
thread_local ThreadStatus * main_thread = nullptr;
#if !defined(SANITIZER) #if !defined(SANITIZER)
namespace namespace

View File

@ -102,8 +102,16 @@ public:
using ThreadGroupStatusPtr = std::shared_ptr<ThreadGroupStatus>; using ThreadGroupStatusPtr = std::shared_ptr<ThreadGroupStatus>;
/**
extern thread_local ThreadStatus * current_thread; * We use **constinit** here to tell the compiler the current_thread variable is initialized.
* If we didn't help the compiler, then it would most likely add a check before every use of the variable to initialize it if needed.
* Instead it will trust that we are doing the right thing (and we do initialize it to nullptr) and emit more optimal code.
* This is noticeable in functions like CurrentMemoryTracker::free and CurrentMemoryTracker::allocImpl
* See also:
* - https://en.cppreference.com/w/cpp/language/constinit
* - https://github.com/ClickHouse/ClickHouse/pull/40078
*/
extern thread_local constinit ThreadStatus * current_thread;
/** Encapsulates all per-thread info (ProfileEvents, MemoryTracker, query_id, query context, etc.). /** Encapsulates all per-thread info (ProfileEvents, MemoryTracker, query_id, query context, etc.).
* The object must be created in thread function and destroyed in the same thread before the exit. * The object must be created in thread function and destroyed in the same thread before the exit.