Skip to content

Reorganize #ifdef guards and private members in BoundedSPSCQueueImpl#917

Open
xuetianhao98 wants to merge 2 commits into
odygrd:masterfrom
xuetianhao98:refactor/macro-guards
Open

Reorganize #ifdef guards and private members in BoundedSPSCQueueImpl#917
xuetianhao98 wants to merge 2 commits into
odygrd:masterfrom
xuetianhao98:refactor/macro-guards

Conversation

@xuetianhao98
Copy link
Copy Markdown

Moves QUILL_CACHE_LINE_MASK, _last_flushed_writer_pos, and _last_flushed_reader_pos inside #ifdef QUILL_X86ARCH guards, since they are only referenced within x86-specific cache-line flushing logic. Also regroups the remaining position-tracking members for better locality.

These members serve no purpose on non-x86 targets. Guarding them properly reduces object size on other architectures, prevents accidental misuse outside x86 code paths, and makes the platform-specific intent explicit at a glance.

@odygrd
Copy link
Copy Markdown
Owner

odygrd commented Apr 20, 2026

Hey, thanks for the PR!

Two issues:

  1. _last_flushed_writer_pos / _last_flushed_reader_pos can be guarded with #ifdef QUILL_X86ARCH (the alignas already reserves the full cache line), but they need to stay in place with two separate #ifdef blocks — one on the writer's line, one on the reader's. The PR moves both into a single block at the top of private:, which puts them on the wrong cache line.

e.g.

    alignas(QUILL_CACHE_LINE_ALIGNED) std::atomic<integer_type> _atomic_writer_pos{0};
    alignas(QUILL_CACHE_LINE_ALIGNED) integer_type _writer_pos{0};
    integer_type _reader_pos_cache{0};
  #ifdef QUILL_X86ARCH
    integer_type _last_flushed_writer_pos{0};
  #endif

    alignas(QUILL_CACHE_LINE_ALIGNED) std::atomic<integer_type> _atomic_reader_pos{0};
    alignas(QUILL_CACHE_LINE_ALIGNED) integer_type _reader_pos{0};
    mutable integer_type _writer_pos_cache{0};
  #ifdef QUILL_X86ARCH
    integer_type _last_flushed_reader_pos{0};
  #endif
  1. Swapping _reader_pos_cache and _writer_pos_cache inverts locality. _reader_pos_cache is only touched by the writer, _writer_pos_cache only by the reader — the current layout is intentional. The PR puts each on the wrong thread's cache line, causing false sharing on the hot path.

@xuetianhao98
Copy link
Copy Markdown
Author

Hey, thanks for the PR!

Two issues:

  1. _last_flushed_writer_pos / _last_flushed_reader_pos can be guarded with #ifdef QUILL_X86ARCH (the alignas already reserves the full cache line), but they need to stay in place with two separate #ifdef blocks — one on the writer's line, one on the reader's. The PR moves both into a single block at the top of private:, which puts them on the wrong cache line.

e.g.

    alignas(QUILL_CACHE_LINE_ALIGNED) std::atomic<integer_type> _atomic_writer_pos{0};
    alignas(QUILL_CACHE_LINE_ALIGNED) integer_type _writer_pos{0};
    integer_type _reader_pos_cache{0};
  #ifdef QUILL_X86ARCH
    integer_type _last_flushed_writer_pos{0};
  #endif

    alignas(QUILL_CACHE_LINE_ALIGNED) std::atomic<integer_type> _atomic_reader_pos{0};
    alignas(QUILL_CACHE_LINE_ALIGNED) integer_type _reader_pos{0};
    mutable integer_type _writer_pos_cache{0};
  #ifdef QUILL_X86ARCH
    integer_type _last_flushed_reader_pos{0};
  #endif
  1. Swapping _reader_pos_cache and _writer_pos_cache inverts locality. _reader_pos_cache is only touched by the writer, _writer_pos_cache only by the reader — the current layout is intentional. The PR puts each on the wrong thread's cache line, causing false sharing on the hot path.

Wow!Thanks for the detailed review and for pointing this out. Your review helped me understand this data structure at a deeper level. I didn’t consider the cache line layout deeply enough when making those changes, especially the implications around locality and false sharing.

I’ve now addressed both issues following your suggestions:

  • Restored the separate #ifdef placements to keep the variables on their intended cache lines.
  • Reverted the cache variable ordering to preserve the original locality assumptions.

A new commit has been pushed with these fixes. Please let me know if anything still looks off.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants