-
Notifications
You must be signed in to change notification settings - Fork 367
Description
The WGSL spec section on atomic types describes restrictions which do not apply to read-modify operations:
In WGSL, atomic modifications are mutually ordered, for each object. That is, during execution of a shader stage, for each atomic object A, all agents observe the same order of modification operations applied to A. The ordering for distinct atomic objects may not be related in any way; no causality is implied.
The spec makes broad no-guarantees which avoid needing to work out semantics around memory coherency and visibility, e.g. the issue of data flushing through the cache. However, these issues only apply to simple atomic load/store. Especially atomic store, in a relaxed memory model, allows a "fire and forget" model, where "atomic" only relates to other issues such as compiler optimizations.
In the context of shading languages, plain atomic-load or atomic-store operations are not that common. What is more common is a separate class of atomic operations with stronger guarantees of atomic coherence. These are read-modify operations like atomicAdd(), atomicExchange, and atomicCompareExchange(). For atomic objects in global memory, these objects necessarily have strong guarantees between separate atomic objects. For example:
Thread A {
atomicExchange(&buf[payloadAddr], payload); // atomic store using read-modify
atomicExchange(&buf[sentinelAddr], 1u);
}
Thread B {
while (atomicExchange(&buf[sentinelAddr], 0u) < 1u) {}
let payload = atomicExchange(&buf[payloadAddr], 0u);
}
The key distinction is, for an atomicExchange() or atomicAdd(), control cannot return to the thread until global memory has been accessed. This implies the written value has also become visible in global memory by the time control returns to the writing thread.
The spec should distinguish between basic atomic load/store, and atomic read-modify operations. Read-modify operations are subject to ordering guarantees between different objects.
The restrictions described by the current spec disallow message-passing patterns which are useful in things like concurrent queues. But these patterns are actually supported on any hardware that implements atomic read-write operations.
This could be an alternative adding volatile atomic syntax #978