Skip to content

Remove graph_lock from the _schema_at hot path #128

Description

@jd-lara

Follow-up from #126, raised in review.

_schema_at (src/runtime.jl) now caches subschema views in spec.subschemas, guarded by spec.graph_lock:

cached = lock(() -> get(spec.subschemas, key, nothing), spec.graph_lock)
cached === nothing || return cached
schema = _build_schema_at(spec, descriptor, direction)
lock(() -> (spec.subschemas[key] = schema), spec.graph_lock)

Every lookup takes the lock once, and the first lookup of a key takes it twice. Before #126 this path was lock-free once the graph existed, but it rebuilt the view on every call. Uncontended, the lock costs about 200 ns per call. Under multi-threaded decoding it serializes lookups.

The lock is required: subschemas is a plain Dict written by concurrent decoders, so the read cannot simply drop it.

Options:

  • Precompute views for all known descriptors when the graph is built. Descriptors are per-call-site constants in generated code, so this needs codegen to register them.
  • Keep an immutable cache and swap it atomically on miss. Reads become lock-free, and a miss copies the cache.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions