Honest measured pipeline efficiency: two timing fixes
Two related issues caused measured pipeline efficiency to look worse than the simulator's actual behavior: 1. DMA timing recorded too early. The op-log start timestamp for a DMA op fired when the request entered the queue, and the DMA channel was released as soon as the request was issued. Back-to-back DMAs therefore appeared to grab the channel simultaneously, with per-op duration drifting upward as queue depth grew - an artifact, not real cost. Fix: defer the start timestamp until after the channel is acquired, and hold the channel through the full HBM round-trip until the response returns. Per-op duration is now constant and equal to the actual transfer interval; serialization is visible as queue wait, not as inflated service time. 2. Sweep timing window folded in pre-composite work. The PE timing window spanned every PE engine record, which included the upfront pinned-operand DMA issued before the composite GEMM begins. For large-K shapes that one-shot load can be nearly half of the window, conflating operand-staging cost with composite-pipeline behavior. Fix: add a second window scoped to the composite pipeline by filtering op_log records to those tagged with a tile-pipeline stage; the legacy operand-load path is untagged and naturally excluded. For 32x3072x32 load_ref the window drops from 1765ns to 992ns and measured eff lines up with the steady-state DMA-bound stage limit instead of being penalized for the one-time load. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -138,8 +138,16 @@ class PeEngineBase(ComponentBase):
|
||||
env.process(self._forward_txn(env, msg))
|
||||
|
||||
def _handle_with_hooks(self, env: simpy.Environment, pe_txn: Any) -> Generator:
|
||||
"""Wrap handle_command with op log hooks on the inner command."""
|
||||
self._on_process_start(env, pe_txn.command)
|
||||
"""Wrap handle_command with op log hooks on the inner command.
|
||||
|
||||
Subclasses that need to defer record_start until after a resource
|
||||
wait (e.g. pe_dma's DMA-channel acquire) set
|
||||
``_DEFER_RECORD_START = True`` and call
|
||||
``self._on_process_start(env, pe_txn.command)`` themselves at the
|
||||
post-wait moment. record_end still fires here.
|
||||
"""
|
||||
if not getattr(self, "_DEFER_RECORD_START", False):
|
||||
self._on_process_start(env, pe_txn.command)
|
||||
yield from self.handle_command(env, pe_txn)
|
||||
self._on_process_end(env, pe_txn.command)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user