Skip to content

Avoid false-sharing #11986

Closed
Closed
@bartoszmodelski

Description

@bartoszmodelski

False-sharing is pretty bad for performance of lock-free algorithms. There's many known results. This classic paper is a little old but for example:

  • 80% reduction in wall-clock time on linear regression claimed by Intel's coobkook.
  • In the case of multicore OCaml, @anmolsahoo25 found a 23% reduction in wall-clock time on a benchmark with just two threads.

We've had some discussion on lockfree. There's probably at least 2 acceptable solutions there. The rest of this issue describes both. Let me know what you think, I'm happy to open a PR with either.

Expose memory-aligned allocation

A somewhat principled C-style solution is to just call posix_memalign / aligned_alloc (C11) to get a block of memory, which occupies entire cache line(s). It makes it impossible for the cache line to be falsely-shared. It's also useful for doing math quickly (SSE, AVX).

I claim we can do this relatively easily by sending these allocations into large_allocate with a special path that uses aligned_alloc (rather than malloc). Current threshold for large alloc is 129, while cache line is 64 on most systems, so we're pretty close to using this infra anyway.

See this approach here.

Add padding

A nice workaround is to just add padding. If block spans multiple cache lines and the middle is accessed then alignment doesn't matter. @polytypic implemented it in multicore-magic. A disadvantage here is that we cannot pad area before the atomic (or it wouldn't be a valid Atomic.t), so we can still have accidental false-sharing if some other atomics in the program have not been padded. The positive part is that it's super simple.

If that's the blessed way to go forward, I would propose to add that to Obj or/and create Atomic.make_padded.

Other ideas

@sadiqj mentioned making Atomic.t unboxed to let us pad records like in Java or Golang. It sounds reasonable but I do not have the expertise to create a POC.

cc @kayceesrk

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions