You need to take two things into consideration with regard to performance when you use atomic variables.
First, the RM only guarantees that access to atomic variables be atomic, but has nothing to say about how this is achieved, though there is a strong implication that this should not be achieved by explicit locking code. Indeed, GNAT never generates any locking code for atomic variable access; it will simply reject any attempt to make a variable or type atomic if the atomic access cannot be achieved without such locking code.
That being said, it’s important to understand that you cannot assume the the program will always access the entire variable. Consider this example:
type R is record A,B,C,D : Character; end record; for R'Size use 32; for R'Alignment use 4; RV : R; pragma Atomic (RV); X : Character; ... X := RV.B;
You cannot assume that the reference to RV.B
will read the entire 32-bit
variable with a single load instruction. It is perfectly legitimate, if
the hardware allows it, to do a byte read of just the B
field. This read
is still atomic, which is all the RM requires. GNAT can and does take
advantage of this, depending on the architecture and optimization level.
Any assumption to the contrary is non-portable and risky. Even if you
examine the assembly language and see a full 32-bit load, this might
change in a future version of the compiler.
If your application requires that all accesses to RV
in this
example be full 32-bit loads, you need to make a copy for the access
as in:
declare RV_Copy : constant R := RV; begin X := RV_Copy.B; end;
Now the reference to RV
must read the whole variable.
Actually, one can imagine some compiler which figures
out that the whole copy is not required (because only
the B
field is actually accessed), but GNAT
certainly won’t do that, and we don’t know of any
compiler that would not handle this right, and the
above code will in practice work portably across
all architectures (that permit the Atomic declaration).
The second issue with atomic variables has to do with
the possible requirement of generating synchronization
code. For more details on this, consult the sections on
the pragmas Enable/Disable_Atomic_Synchronization in the
:title:GNAT Reference Manual
. If performance is critical, and
such synchronization code is not required, you may find it
useful to disable it.