Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ SchedulerContext::PublishHandle SchedulerContext::prepare_subtask_to_core(
uint32_t buf_idx = reg_task_id & 1u;
PTO2DispatchPayload &payload = payload_per_core_[core_id][buf_idx];
DeferredCompletionSlab *deferred_slab = &deferred_slab_per_core_[core_id][buf_idx];
// Pull ownership of the per-core dispatch buffers before the hot stores below.
__builtin_prefetch(reinterpret_cast<const char *>(&payload), 1, 3);
__builtin_prefetch(reinterpret_cast<const char *>(&payload) + 64, 1, 3);
__builtin_prefetch(reinterpret_cast<const char *>(deferred_slab), 1, 3);
deferred_slab->count = 0;
deferred_slab->error_code = PTO2_ERROR_NONE;
AsyncCtx async_ctx = AsyncCtx::make(slot_state.task->task_id, deferred_slab);
Comment on lines +165 to 171

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The prefetch for payload only covers the first two cache lines (offsets 0 and 64). However, build_payload unconditionally writes to local_context (offset 384+) and not_ready (offset 504), which reside in cache lines 6 and 7. Prefetching these tail cache lines prevents RFO cache misses on these hot stores.

Additionally, deferred_slab is written to immediately after its prefetch instruction, leaving no execution cycles to hide memory latency. Moving the construction of async_ctx before the writes provides a small execution window to overlap the prefetch.

    // Pull ownership of the per-core dispatch buffers before the hot stores below.
    __builtin_prefetch(reinterpret_cast<const char *>(&payload), 1, 3);
    __builtin_prefetch(reinterpret_cast<const char *>(&payload) + 64, 1, 3);
    __builtin_prefetch(reinterpret_cast<const char *>(&payload) + 384, 1, 3);
    __builtin_prefetch(reinterpret_cast<const char *>(&payload) + 448, 1, 3);
    __builtin_prefetch(reinterpret_cast<const char *>(deferred_slab), 1, 3);

    // Construct AsyncCtx first to give prefetch instructions some cycles to run
    AsyncCtx async_ctx = AsyncCtx::make(slot_state.task->task_id, deferred_slab);
    deferred_slab->count = 0;
    deferred_slab->error_code = PTO2_ERROR_NONE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ void SchedulerContext::dispatch_subtask_to_core(
uint32_t buf_idx = reg_task_id & 1u;
PTO2DispatchPayload &payload = payload_per_core_[core_id][buf_idx];
DeferredCompletionSlab *deferred_slab = &deferred_slab_per_core_[core_id][buf_idx];
// Pull ownership of the per-core dispatch buffers before the hot stores below.
__builtin_prefetch(reinterpret_cast<const char *>(&payload), 1, 3);
__builtin_prefetch(reinterpret_cast<const char *>(&payload) + 64, 1, 3);
__builtin_prefetch(reinterpret_cast<const char *>(deferred_slab), 1, 3);
deferred_slab->count = 0;
deferred_slab->error_code = PTO2_ERROR_NONE;
AsyncCtx async_ctx = AsyncCtx::make(slot_state.task->task_id, deferred_slab);
Comment on lines +149 to 155

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The prefetch for payload only covers the first two cache lines (offsets 0 and 64). However, build_payload unconditionally writes to local_context (offset 384+), which resides in cache line 6. Prefetching this tail cache line prevents RFO cache misses on these hot stores.

Additionally, deferred_slab is written to immediately after its prefetch instruction, leaving no execution cycles to hide memory latency. Moving the construction of async_ctx before the writes provides a small execution window to overlap the prefetch.

    // Pull ownership of the per-core dispatch buffers before the hot stores below.
    __builtin_prefetch(reinterpret_cast<const char *>(&payload), 1, 3);
    __builtin_prefetch(reinterpret_cast<const char *>(&payload) + 64, 1, 3);
    __builtin_prefetch(reinterpret_cast<const char *>(&payload) + 384, 1, 3);
    __builtin_prefetch(reinterpret_cast<const char *>(deferred_slab), 1, 3);

    // Construct AsyncCtx first to give prefetch instructions some cycles to run
    AsyncCtx async_ctx = AsyncCtx::make(slot_state.task->task_id, deferred_slab);
    deferred_slab->count = 0;
    deferred_slab->error_code = PTO2_ERROR_NONE;

Expand Down
Loading