Does the C++11 memory model allow hoisting relaxed atomic loads out of loops?

北战南征 提交于 2019-12-01 14:19:54

问题


Consider the following code:

#include <atomic>

extern std::atomic<int> i;

void f(void)
{
  while (!i.load(std::memory_order_relaxed))
      ;
}

I'm looking for a citation from the C++11 standard that says that the compiler is not allowed to transform the loop into

  if (!i.load(std::memory_order_relaxed)) {
    while (1)
      ;
  }

I've seen some discussion here but nothing conclusive.

Edit: A previous version of this post called an extern function inside the loop.

Edit 2: For motivation: The book "Effective Java" says that the HotSpot VM performs the following transformation:

while (!done)
    i++;

to

if (!done)
    while (true)
        i++;

even though it's perfectly defined behavior for another thread to change the done variable concurrently.


回答1:


Forget about relaxed, there's no guarantee that an atomic store ever become visible to an atomic load in a different thread. The best you get is the normative encouragement in [atomics.order]/12 (and analogous wording in [intro.progress]/18):

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

...which is not a requirement.

(C11 has identical wording in §7.11.3/16)

Since hoisting the load leads to behavior indistinguishable from a non-hoisted load where the store never becomes visible, and since the latter is conforming, an implementation is allowed by the as-if rule to hoist the load regardless of the memory order used.



来源:https://stackoverflow.com/questions/40272730/does-the-c11-memory-model-allow-hoisting-relaxed-atomic-loads-out-of-loops

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!