Skip to content

Replace MemoryBarrier with Volatile operations in HashMap#125259

Merged
AaronRobinsonMSFT merged 1 commit intodotnet:mainfrom
AaronRobinsonMSFT:hashmap-volatile-barriers
Mar 7, 2026
Merged

Replace MemoryBarrier with Volatile operations in HashMap#125259
AaronRobinsonMSFT merged 1 commit intodotnet:mainfrom
AaronRobinsonMSFT:hashmap-volatile-barriers

Conversation

@AaronRobinsonMSFT
Copy link
Member

@AaronRobinsonMSFT AaronRobinsonMSFT commented Mar 6, 2026

Replace full MemoryBarrier() fences with narrower VolatileStore (release) and VolatileLoad (acquire) operations in hash.cpp. Full fences (dmb ish on ARM64, mfence on x86) are unnecessarily expensive when only one-directional ordering is needed.

Changes

  • InsertValue: VolatileStore on key publication (release) ensures the value is visible before the key.
  • LookupValue/ReplaceValue/DeleteValue: VolatileLoad on key match (acquire) ensures subsequent value reads are ordered after the key.
  • ReplaceValue: Plain store the new value, then VolatileStore on the key (release) to re-publish it. Readers acquire-load the key via VolatileLoad, forming a proper release-acquire pair on the same address and ensuring they observe either the old or the fully-updated new value.
  • Rehash: VolatileStore on m_rgBuckets (release) ensures new bucket contents are visible before the pointer is published. Readers observe these writes because they enter an EBR critical region (EbrCriticalRegionHolder::EnterCriticalRegion), which executes a full MemoryBarrier() before reading m_rgBuckets.

Impact on ARM64

Site Before After
InsertValue dmb ish + str stlr
Reader key match dmb ish ldar
ReplaceValue write str + dmb ish str + stlr (key re-publish)
Rehash pointer publish dmb ish + str stlr

On x86/x64, MemoryBarrier() emits mfence (or lock or), whereas VolatileLoad/VolatileStore are just compiler fences (TSO provides hardware ordering).

@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR replaces full MemoryBarrier() fences in hash.cpp with narrower VolatileStore (release) and VolatileLoad (acquire) operations. On ARM64, MemoryBarrier() emits a full dmb ish instruction, while stlr/ldar are cheaper one-directional fences. On x86/x64, both are compiler fences (TSO provides hardware ordering), so the change is neutral there.

Changes:

  • InsertValue: Plain write + MemoryBarrier() replaced with VolatileStore (release) on key publication.
  • LookupValue/ReplaceValue/DeleteValue: Plain key comparison + MemoryBarrier() replaced with VolatileLoad (acquire) on key read.
  • Rehash: MemoryBarrier() + plain write replaced with VolatileStore (release) on m_rgBuckets pointer update.

@AaronRobinsonMSFT AaronRobinsonMSFT force-pushed the hashmap-volatile-barriers branch from 361038d to 4fc7b9e Compare March 6, 2026 08:31
@AaronRobinsonMSFT AaronRobinsonMSFT marked this pull request as ready for review March 6, 2026 19:44
Copilot AI review requested due to automatic review settings March 6, 2026 19:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.

Replace full MemoryBarrier() fences with narrower VolatileStore (release)
and VolatileLoad (acquire) operations in hash.cpp. Full fences (dmb ish
on ARM64, mfence on x86) are unnecessarily expensive when only
one-directional ordering is needed.

- InsertValue: VolatileStore on key publication (release) ensures the
  value is visible before the key.
- LookupValue/ReplaceValue/DeleteValue: VolatileLoad on key match
  (acquire) ensures subsequent value reads are ordered after the key.
- ReplaceValue: VolatileStore on value update (release) ensures the new
  value is visible to concurrent readers.
- Rehash: VolatileStore on m_rgBuckets (release) ensures new bucket
  contents are visible before the pointer is published.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AaronRobinsonMSFT AaronRobinsonMSFT force-pushed the hashmap-volatile-barriers branch from 4fc7b9e to 2c9a803 Compare March 6, 2026 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants