Sollte std :: atomic flüchtig sein?

Ich führe einen Thread aus, der ausgeführt wird, bis ein Flag gesetzt ist.

std::atomic<bool> stop(false);

void f() {
  while(!stop.load(std::memory_order_{relaxed,acquire})) {
    do_the_job();
  }
}

Ich frage mich, ob der Compiler die Schleife so ausrollen kann (ich möchte nicht, dass es passiert).

void f() {
  while(!stop.load(std::memory_order_{relaxed,acquire})) {
    do_the_job();
    do_the_job();
    do_the_job();
    do_the_job();
    ... // unroll as many as the compiler wants
  }
}

Es wird gesagt, dass Volatilität und Atomizität orthogonal sind, aber ich bin ein bisschen verwirrt. Kann der Compiler den Wert der atomaren Variablen zwischenspeichern und die Schleife ausrollen? Wenn der Compiler die Schleife abrollen kann, dann muss ich wohl @ setzvolatile an die Flagge, und ich möchte sicher sein.

Sollte ich @ setzvolatile?

Es tut mir leid, dass ich mehrdeutig bin. Ich (rate mal, dass ich) verstehe, was Nachbestellung ist und wasmemory_order_*s meine, und ich bin sicher, ich verstehe voll und ganz, wasvolatile is.

Ich denke derwhile() loop kann als unendliches @ transformiert werdif Aussagen wie diese.

void f() {
  if(stop.load(std::memory_order_{relaxed,acquire})) return;
  do_the_job();
  if(stop.load(std::memory_order_{relaxed,acquire})) return;
  do_the_job();
  if(stop.load(std::memory_order_{relaxed,acquire})) return;
  do_the_job();
  ...
}

Da die angegebenen Speicherreihenfolgen nicht verhindern, dass die Sequenced-Before-Operationen an der atomaren Last vorbeigehen, kann sie meiner Meinung nach neu angeordnet werden, wenn sie nicht flüchtig ist.

void f() {
  if(stop.load(std::memory_order_{relaxed,acquire})) return;
  if(stop.load(std::memory_order_{relaxed,acquire})) return;
  if(stop.load(std::memory_order_{relaxed,acquire})) return;
  ...
  do_the_job();
  do_the_job();
  do_the_job();
  ...
}

Wenn das Atom nicht flüchtig ist, kann der Code im schlimmsten Fall sogar so transformiert werden.

void f() {
  if(stop.load(std::memory_order_{relaxed,acquire})) return;

  while(true) {
    do_the_job();
  }
}

Es wird nie eine solch verrückte Implementierung geben, aber ich denke, es ist immer noch eine mögliche Situation. Ich denke, die einzige Möglichkeit, dies zu verhindern, besteht darin,volatile auf die atomare Variable und frage danach.

Es gibt eine Menge Vermutungen, die ich angestellt habe. Bitte sagen Sie mir, wenn irgendetwas an ihnen nicht stimmt.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage