Doc. No.: | WG21/N3786 |
---|---|
Date: | 2013年9月24日 |
Reply to: | Hans-J. Boehm |
Related to: | N3710, LWG 2265 |
Phone: | +1-650-857-3406 |
Email: | Hans.Boehm@hp.com |
We argued in N3710 that the current attempt prohibit out-of-thin-air
results in 29.3p9 [atomics.order] is both insufficient, in that it leaves
it largely impossible to reason about programs with
memory_order_relaxed
, and seriously
harmful, in that it arguably disallows all reasonable implementations
of memory_order_relaced
on architectures like ARM and
POWER. This proposal attempts
to address the latter "seriously harmful" part for C++14, without
addressing the "insufficient" part, which would still need to be addressed
in C++17, possibly along the lines of N3710.
This proposal thus eliminates some amount of complicated standardese that we actually want vendors like ARM and IBM to ignore.
There is no consensus in SG1 for a more extensive proposal, such as that in N3710, at this time, i.e. in time for C++14.
This removes the current badly formulated requirement, and instead promotes the existing note discouraging "out-of-thin-air" results to normative encouragment.
The core problem here is that we do not know (after 10 years of failed attempts, originally in a Java context) how to precisely state this requirement without strengthening it so that it impacts code performance. (See N3710 for details.) Thus it remains of little use to anyone trying to formulate a precise correctness argument. It is roughly analogous to our current statements about progress guarantees, which are also phrased as normative encouragement in large part because they would be extremely difficult to make precise while remaining implementable.
Change 29.3p9-11 [atomics.order] as follows
(削除) An atomic store shall only store a value that has been computed from constants and program input values by a finite sequence of program evaluations, such that each evaluation observes the values of variables as computed by the last prior assignment in the sequence. The ordering of evaluations in this sequence shall be such that: (削除ここまで)
(削除) if an evaluation B observes a value computed by A in a different thread, then B does not happen before A, and (削除ここまで)(削除) if an evaluation A is included in the sequence, then every evaluation that assigns to the same variable and happens before A is included. (削除ここまで)(追記) Implementations should ensure that no "out-of-thin-air" values are computed that circularly depend on their own computation. (追記ここまで)
(削除) [ Note: The second requirement disallows "out-of-thin-air" or "speculative" stores of atomics when relaxed atomics are used. Since unordered operations are involved, evaluations may appear in this sequence out of thread order. For example, with x and y initially zero, (削除ここまで)(削除) // Thread 1: r1 = y.load(memory_order_relaxed); x.store(r1, memory_order_relaxed); // Thread 2: r2 = x.load(memory_order_relaxed); y.store(42, memory_order_relaxed); (削除ここまで)
(削除) is allowed to producer1
=r2
= 42. The sequence of evaluations justifying this consists of: (削除ここまで)(削除) y.store(42, memory_order_relaxed); r1 = y.load(memory_order_relaxed); x.store(r1, memory_order_relaxed); r2 = x.load(memory_order_relaxed); (削除ここまで)
(削除) On the other hand, (削除ここまで)(追記) [Note: For example, withx
andy
initially zero, (追記ここまで)// Thread 1: r1 = y.load(memory_order_relaxed); x.store(r1, memory_order_relaxed); // Thread 2: r2 = x.load(memory_order_relaxed); y.store(r2, memory_order_relaxed);
(削除) may (削除ここまで)(追記) should (追記ここまで) not producer1
=(追記) = (追記ここまで)r2
=(追記) = (追記ここまで) 42, since (追記) the store of 42 toy
is only possible if the store tox
stores 42, which circularly depends on the store toy
storing 42. Note that without this restriction, such an execution is possible. (追記ここまで)(削除) there is no sequence of evaluations that results in the computation of 42. In the absence of "relaxed" operations and read-modify-write operations with weaker than-end note ]memory_order_acq_rel
ordering, the second requirement has no impact. (削除ここまで)[ Note:
(削除) The requirements do allow (削除ここまで)(追記) The recommendation similarly disallows (追記ここまで)r1
==r2
== 42 in the following example, withx
andy
(追記) again (追記ここまで) initially zero:// Thread 1: r1 = x.load(memory_order_relaxed); if (r1 == 42) y.store((削除) r1 (削除ここまで)(追記) 42 (追記ここまで), memory_order_relaxed); // Thread 2: r2 = y.load(memory_order_relaxed); if (r2 == 42) x.store(42, memory_order_relaxed);
(削除) However, implementations should not allow such behavior. (削除ここまで)-end note ]