Quantcast
Channel: Active questions tagged atomic - Stack Overflow
Viewing all articles
Browse latest Browse all 115

Prevent reordering of prefetch instruction in c++

$
0
0

Usecase: I have an SPSC queue in multi-thread setup, where I want to prefetch the write_index's mempool on a successful pop.

Following is my original implementation:

void process(){  if(spsc_queue->pop())  {     // Do some pre-processing     auto r_index = spsc_queue->read_index.load(memory_order_relaxed);     auto val = mempool_[r_index+1];     // logic to use val follows  }}

I have seen latency improvements when I change the setup to include data prefetching:

void process(){  if(spsc_queue->pop())  {    auto r_index = spsc_queue->read_index.load(memory_order_releaxed);    __builtin_prefetch(mempool_ + r_index + 1, 0, 0);    // Do some pre-processing    auto val = mempool_[r_index + 1];    // logic to use val follows  }}

Issue is: Given that pop will be inlined, I am not sure if the compiler / processor re-ordering is shifting the prefetch instruction to execute even if pop fails. Consider:

void pop(){  auto w_index = write_index.load(memory_order_acquire);  auto r_index = read_index.load(memory_order_relaxed);  // What if builtin_prefetch is reordered to before this return.  if (w_index == r_index) return false; // early return for pop fail  // update other structs  return true;}

I want to ensure that the prefetching only occurs if pop() returns true. Not otherwise. Things I tried:

  1. using mfence : If I place mfence just after the early return, its bound to ensure non-reordering at compiler / processor level. But that is going to cost me additional latency, since mfence will is a costly instruction.

  2. Measure the cache accesses in pop fail path. In case it rises, its possible that prefetch is being reordered at processor level (not conclusive).

  3. Compiler reordering can be prevented using compiler native support. Issue is processor level reordering.

  4. Accessing a volatile after early return, and then issueing the prefetch instruction. From my readings.. it seems like volatile only syncrhonizes with other volatile so in my case it won't be helpful.

Is there any deterministic way that I can be sure of the prefetch instruction isn't executed on pop fail path?

Compiler:

$ gcc -vgcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0Target: x86_64-linux-gnu

TIA.


Viewing all articles
Browse latest Browse all 115

Latest Images

Trending Articles



Latest Images