合并连续原子变量的存储/加载 [英] Combining stores/loads of consecutive atomic variables

查看:39
本文介绍了合并连续原子变量的存储/加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

引用(略过时)的纸张(由Hans Boehm撰写,位于原子操作下)。它提到了内存模型(当时提出的)不会阻止优化编译器将相同变量上的一系列加载或存储组合到单个加载中。他的示例如下所示(已更新为有望更正当前语法):

Referring to a (slightly dated) paper by Hans Boehm, under "Atomic Operations". It mentions that the memory model (proposed at the time) would not prevent an optimizing compiler from combining a sequence of loads, or stores, on the same variable from being combined into a single load. His example is as follows (updated to hopefully correct current syntax):

给出

atomic<int> v;

代码

while( v.load( memory_order_acquire ) ) { ... }

优化为:

int a = v.load(memory_order_acquire);
while(a) { ... }

显然,这很糟糕,因为他状态。现在我的问题是,由于本文有些陈旧,所以当前的C ++ 0x内存模型是否会阻止这种类型的优化,或者在技术上仍允许这种优化?

Obviously this would be bad, as he states. Now my question is, as the paper is a bit old, does the current C++0x memory model prevent this type of optimization, or is it still technically allowed?

我对标准的阅读似乎倾向于不被接受,但是使用获取语义使它不太清楚。例如,如果它是 seq_cst,则该模型似乎可以保证负载必须分担访问的全部顺序,并且仅加载一次该值似乎违反了顺序(因为它破坏了关系发生之前的顺序)。

My reading of the standard would seem to lean towards it being disallowed, but the use "acquire" semantics makes it less clear. For example if it were "seq_cst" the model seems to guarantee that the load must partake in a total ordering on the access and loading the value only once would thus seem to violate ordering (as it breaks the sequence happens before relationship).

对于获取,我将29.3.2解释为不会发生这种优化,因为必须通过获取操作来观察任何释放操作。

For acquire I interpret 29.3.2 to mean that this optimization can not occur, since any "release" operation must be observed by the "acquire" operation. Doing only one acquire would seem not valid.

所以我的问题是当前模型(在待定标准中)是否会不允许这种类型的优化?如果是的话,那么哪一部分专门禁止呢?如果不是,使用 volatile 原子能解决问题吗?

So my question is whether the current model (in the pending standard) would disallow this type of optimization? And if yes, then which part specifically forbids it? If no, does using a volatile atomic solve the problem?

另外,如果装入操作有一个

And for bonus, if the load operation has a "relaxed" ordering is the optimization then allowed?

推荐答案

C ++ 0x标准试图禁止这种优化。

The C++0x standard attempts to outlaw this optimization.

相关词来自29.3p13:

The relevant words are from 29.3p13:


实施应使原子存储对原子可见

Implementations should make atomic stores visible to atomic loads within a reasonable amount of time.

如果正在执行加载的线程仅发出一条加载指令,则违反了该指令,好像第一次错过写操作一样,它将永远看不到它。加载使用哪种内存顺序都没有关系, memory_order_seq_cst memory_order_relaxed 都是相同的。

If the thread that is doing the load only ever issues one load instruction then this is violated, as if it misses the write the first time, it will never see it. It doesn't matter which memory ordering is used for the load, it is the same for both memory_order_seq_cst and memory_order_relaxed.

但是,允许以下优化 ,除非循环中存在强制执行排序的内容:

However, the following optimization is allowed, unless there is something in the loop that forces an ordering:

while( v.load( memory_order_acquire ) ) {
    for(unsigned __temp=0;__temp<100;++__temp) {
        // original loop body goes here
    }
}

ie编译器可以生成偶尔执行任意实际负载的代码。甚至允许 memory_order_seq_cst 这样做,除非循环中还有其他 memory_order_seq_cst 操作,因为这等效于运行100次迭代

i.e. the compiler can generate code that executes the actual loads arbitrarily infrequently, provided it still executes them. This is even permitted for memory_order_seq_cst unless there are other memory_order_seq_cst operations in the loop, since this is equivalent to running 100 iterations between any memory accesses by other threads.

顺便说一句,使用 memory_order_acquire 不会产生影响。您描述的是---不需要查看发布操作(上面引用的29.3p13除外),只是如果它确实看到发布操作,那么它将对 other 访问。

As an aside, the use of memory_order_acquire doesn't have the effect you describe --- it is not required to see release operations (other than by 29.3p13 quoted above), just that if it does see the release operation then it imposes visibility constraints on other accesses.

这篇关于合并连续原子变量的存储/加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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