xcomm/docs/xdata_xclock_optimizations.md

3.6 KiB

XData / XClock / XPort Optimization Notes (1,2,3,5)

Scope

Only optimization items 1 / 2 / 3 / 5 are covered. No changes for divider algorithm (4) or runtime fast_mode advice (6).


1) XData::_update_shadow lower cost when no callbacks

Location: src/xdata.cpp : XData::_update_shadow Current: Every read/write does shadow compare/copy even when no callbacks. Idea:

  • When has_on_change_cbs == false, skip per-element compare and callback logic.
  • Keep shadow baseline consistent to avoid missing the first change after callbacks are added.

Risk:

  • If shadow is not updated while no callbacks, registering a callback later can mis-detect changes.

Mitigation:

  • On OnChange registration, refresh shadow (or copy current data to shadow) as the baseline.

Expected gain:

  • Significant when many signals have no callbacks and are read/written frequently.

2) XData::_need_write use memcmp/memcpy

Location: src/xdata.cpp : XData::_need_write / _update_last_write Current: Element-by-element compare and copy for vec data. Idea:

  • Use memcmp for change detection on xsvLogicVecVal arrays.
  • Use memcpy to update last_pVecData on change.

Risk:

  • Requires contiguous array layout (xsvLogicVecVal array) and correct vecSize.

Expected gain:

  • Reduced branch/loop overhead for wide buses and frequent writes.

3) XPort hot-iteration vector

Location: src/xport.cpp / include/xspcomm/xport.h Current: WriteOnRise/Fall/ReadFresh iterate std::map every time. Idea:

  • Keep map for lookups.
  • Add a std::vector<XData*> for hot loops (Write/Read/SetZero/String).
  • Maintain vector in Add/Del/SelectPins/Connect.

Risk:

  • Must keep map and vector in sync.
  • Sub-port and SelectPins paths must build correct vectors.

Expected gain:

  • Lower cache-miss and tree-iteration overhead when port count is large.

5) Callback assert cost moved to registration

Location: src/xclock.cpp : _call_back / _add_cb Current: Assert(func != nullptr) on every callback invocation. Idea:

  • Validate in _add_cb (registration), not every call.
  • Or keep runtime assert only in debug builds.

Risk:

  • Release builds lose runtime protection (registration still checks).

Expected gain:

  • Small but measurable reduction when callbacks are many/frequent.

Correctness Fix: Reset last_write state on ReInit

Location: src/xdata.cpp : XData::ReInit, XData::~XData Reason:

  • ReInit does not reset last_is_write/last_pVecData, which can leave stale pointers and sizes after width changes.
  • With memcmp/memcpy optimization, stale last_pVecData can cause OOB access.

Fix:

  • In ReInit: set last_is_write = false, last_mLogicData = 0; free and null last_pVecData if allocated.
  • In destructor: free last_pVecData to avoid leak.

Behavior impact:

  • No functional change; prevents stale state and memory leak.

Correctness Fix: ReInit memory management

Location: src/xdata.cpp : XData::ReInit / ~XData Reason:

  • ReInit allocates pVecData/__pVecData/pinbind_vec with calloc but does not free old allocations on repeated ReInit (leak).
  • Destructor used delete for calloc memory (UB). Fix:
  • ReInit frees old pVecData/__pVecData/pinbind_vec (after deleting PinBind*).
  • Destructor frees pVecData/__pVecData/pinbind_vec (after deleting PinBind*). Behavior impact:
  • No functional change; prevents leaks and UB on repeated ReInit.

Correctness Fix: validate checks all bval words

Location: src/xdata.cpp : XData::_update_shadow Reason:

  • validate only checks pVecData[0].bval, missing X/Z in higher words. Fix:
  • Check pVecData[i].bval in the loop; any nonzero makes validate=false. Behavior impact:
  • Callback validity flag becomes correct for wide vectors.