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
Switch FastTimerService to using a local thread observer #33261
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
|
||
// system headers | ||
#include <unistd.h> | ||
#include <pthread.h> | ||
|
||
// C++ headers | ||
#include <chrono> | ||
|
@@ -455,9 +456,32 @@ class FastTimerService : public tbb::task_scheduler_observer { | |
std::vector<ResourcesPerJob> run_summary_; // whole event time accounting per-run | ||
std::mutex summary_mutex_; // synchronise access to the summary objects across different threads | ||
|
||
// per-thread quantities, lazily allocated | ||
tbb::enumerable_thread_specific<Measurement, tbb::cache_aligned_allocator<Measurement>, tbb::ets_key_per_instance> | ||
threads_; | ||
// | ||
struct ThreadGuard { | ||
struct specific_t { | ||
specific_t(AtomicResources& r) : resource_(r), live_(true) {} | ||
~specific_t() = default; | ||
|
||
Measurement measurement_; | ||
AtomicResources& resource_; | ||
bool live_; | ||
}; | ||
|
||
ThreadGuard(); | ||
~ThreadGuard() = default; | ||
|
||
static void retire_thread(void* t); | ||
|
||
bool register_thread(FastTimerService::AtomicResources& r); | ||
Measurement& thread(); | ||
void finalize(); | ||
|
||
tbb::concurrent_vector<std::unique_ptr<specific_t>> thread_resources_; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually it needs to be |
||
pthread_key_t key_; | ||
}; | ||
|
||
// | ||
ThreadGuard guard_; | ||
|
||
// atomic variables to keep track of the completion of each step, process by process | ||
std::unique_ptr<std::atomic<unsigned int>[]> subprocess_event_check_; | ||
|
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.
If I understand correctly,
retire_thread
is called when the worker thread exits.Why not call it from
on_scheduler_exit
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.
Monitoring the primary arena,
on_scheduler_entry
andon_scheduler_exit
get called many times as threads get moved between different arenas, and there's no way to tell when the call toon_scheduler_exit
is the final exit. This is the only reliable way I could think of to catch if a thread gets deleted before the end job sequence.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.
OK, so with this approach, the time (and resources) spent by a thread outside the main arena would be accounted as "overhead", right ?
Which is not a bad thing.
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 that with either the global observer or this PR, what gets measured as overhead is the time outside of any defined CMS module, irrespective of the arena. With the global observer you were getting one call to
on_scheduler_enter
andon_scheduler_exit
per thread, and I'm trying to replicate that with the observer on the primary arena.