Fixing task system worker tracy utilization plot on exit. (#17821)
It was never resetting the idle flag and leaving the plot at non-zero
values on exit.
diff --git a/runtime/src/iree/task/worker.c b/runtime/src/iree/task/worker.c
index f4ffed8..5bebaa5 100644
--- a/runtime/src/iree/task/worker.c
+++ b/runtime/src/iree/task/worker.c
@@ -140,6 +140,37 @@
IREE_TRACE_ZONE_END(z0);
}
+// Marks the worker as "active" (scheduling work or executing it).
+// The idle mask is accessed with 'relaxed' order because it's just a hint.
+static void iree_task_worker_mark_active(iree_task_worker_t* worker) {
+ iree_task_affinity_set_t old_idle_mask =
+ iree_atomic_task_affinity_set_fetch_and(
+ &worker->executor->worker_idle_mask, ~worker->worker_bit,
+ iree_memory_order_relaxed);
+ (void)old_idle_mask;
+ IREE_TRACE_PLOT_VALUE_F32(
+ worker->executor->trace_name,
+ old_idle_mask
+ ? (100.0f -
+ 100.0f * (iree_task_affinity_set_count_ones(old_idle_mask) - 1) /
+ (float)worker->executor->worker_count)
+ : 100.0f);
+}
+
+// Marks the worker as "idle" (sleeping/spinning waiting to wake).
+// The idle mask is accessed with 'relaxed' order because it's just a hint.
+static void iree_task_worker_mark_idle(iree_task_worker_t* worker) {
+ iree_task_affinity_set_t old_idle_mask =
+ iree_atomic_task_affinity_set_fetch_or(
+ &worker->executor->worker_idle_mask, worker->worker_bit,
+ iree_memory_order_relaxed);
+ (void)old_idle_mask;
+ IREE_TRACE_PLOT_VALUE_F32(
+ worker->executor->trace_name,
+ 100.0f - 100.0f * (iree_task_affinity_set_count_ones(old_idle_mask) + 1) /
+ (float)worker->executor->worker_count);
+}
+
void iree_task_worker_post_tasks(iree_task_worker_t* worker,
iree_task_list_t* list) {
// Move the list into the mailbox. Note that the mailbox is LIFO and this list
@@ -275,19 +306,8 @@
iree_wait_token_t wait_token =
iree_notification_prepare_wait(&worker->wake_notification);
- // The masks are accessed with 'relaxed' order because they are just hints.
- iree_task_affinity_set_t old_idle_mask =
- iree_atomic_task_affinity_set_fetch_and(
- &worker->executor->worker_idle_mask, ~worker->worker_bit,
- iree_memory_order_relaxed);
- (void)old_idle_mask;
- IREE_TRACE_PLOT_VALUE_F32(
- worker->executor->trace_name,
- old_idle_mask
- ? (100.0f -
- 100.0f * (iree_task_affinity_set_count_ones(old_idle_mask) - 1) /
- (float)worker->executor->worker_count)
- : 100.0f);
+ // Now active until we decide to go back to sleep until the next pump.
+ iree_task_worker_mark_active(worker);
// Check state to see if we've been asked to exit.
if (iree_atomic_load_int32(&worker->state, iree_memory_order_acquire) ==
@@ -318,15 +338,7 @@
// We've finished all the work we have scheduled so set our idle flag.
// This ensures that if any other thread comes in and wants to give us
// work we will properly coordinate/wake below.
- old_idle_mask = iree_atomic_task_affinity_set_fetch_or(
- &worker->executor->worker_idle_mask, worker->worker_bit,
- iree_memory_order_relaxed);
- (void)old_idle_mask;
- IREE_TRACE_PLOT_VALUE_F32(
- worker->executor->trace_name,
- 100.0f - 100.0f *
- (iree_task_affinity_set_count_ones(old_idle_mask) + 1) /
- (float)worker->executor->worker_count);
+ iree_task_worker_mark_idle(worker);
// When we encounter a complete lack of work we can self-nominate to check
// the global work queue and distribute work to other threads. Only one
@@ -391,6 +403,9 @@
iree_task_worker_pump_until_exit(worker);
}
+ // Indicate idle immediately before exit.
+ iree_task_worker_mark_idle(worker);
+
IREE_TRACE_ZONE_END(thread_zone);
iree_atomic_store_int32(&worker->state, IREE_TASK_WORKER_STATE_ZOMBIE,
iree_memory_order_release);