如何保证加载在存储发生之前完成? [英] How to guarantee that load completes before store occurs?

查看:73
本文介绍了如何保证加载在存储发生之前完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,如何确保直到* ptr被加载/分配/提取"之后,ptr才会递增?

In the following code, how could one ensure that ptr not incremented until after *ptr has been loaded/assigned/"extracted"?

extern int arr[some_constexpr]; // assume pre-populated
extern int* ptr; // assume points to non-atomic arr
int a = *ptr;
// want "memory barrier/fence" here
++ptr;

原子指针能否确保正确的排序/排序?

Would an atomic pointer ensure the correct ordering/sequencing?

#include <atomic>

extern int arr[some_constexpr];
extern std::atomic<int*> ptr;
int a = *(ptr.load());
// implicit "memory barrier" achieved here by use of atomics?
ptr.store(ptr + 1);

这与两个线程之间共享的无锁队列有关.我想确保与指针关联的数据在更新指针之前不会丢失/损坏.

This relates to a lock-free queue shared between two threads. I want to ensure that the data associated with the pointer is not lost/corrupted before updating the pointer.

推荐答案

ptrstd::atomic<int*>++ptrptr++ptr.fetch_add(1, std::memory_order_acq_rel)时,请确保之前/之后的装载/存储都不会重新排序/在执行此操作之前.

When ptr is std::atomic<int*>, ++ptr, or ptr++ or ptr.fetch_add(1, std::memory_order_acq_rel) ensure that no preceding/following loads/stores get reordered past/before this operation.

++ptrptr++本质上是ptr.fetch_add(1, std::memory_order_seq_cst),而std::memory_order_seq_cst几乎总是过大(无法举一个例子,不是).

++ptr, or ptr++ are essentially ptr.fetch_add(1, std::memory_order_seq_cst) and std::memory_order_seq_cst is almost always an overkill (cannot give an example where it is not).

更高效的单个阅读器是:

int arr[some_constexpr];
std::atomic<int*> ptr;

int* p = ptr.load(std::memory_order_acquire);
int element = *p;
ptr.store(p + 1, memory_order_release);

以上基本上是boost::lockfree::spsc_queue的实现方式.

The above is basically how boost::lockfree::spsc_queue is implemented.

作为旁注,boost::lockfree::spsc_queue是真正的 wait -免费 (最严格的进度非阻塞保证)队列. push/pop操作所执行的操作是1 relaxed负载,1 acquire负载和1 release存储,从根本上讲,实现单生产者-单消费者队列的速度不可能比这快(sans实施质量缺陷)和FIFO顺序保证.它通常用作所有其他队列的基准.您可能想研究一下.

As a side note, boost::lockfree::spsc_queue is a true wait-free (strongest non-blocking guarantee of progress) queue. What push/pop operations do is 1 relaxed load, 1 acquire load and 1 release store and it is fundamentally not possible to implement a single-producer-single-consumer queue faster than that (sans implementation quality defects) with FIFO order guarantee. It is often used as a benchmark for all other queues. You may like to look into it.

这篇关于如何保证加载在存储发生之前完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆