Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is atomic.LoadUint32 necessary?

Tags:

atomic

go

Go's atomic package provides function func LoadUint32(addr *uint32) (val uint32). I looked into the assembly implementation:

TEXT ·LoadUint32(SB),NOSPLIT,$0-12
MOVQ    addr+0(FP), AX
MOVL    0(AX), AX
MOVL    AX, val+8(FP)
RET

which basically load the value from the memory address and return it. I'm wondering if we have a uint32 pointer(addr) x, what is the difference between calling atomic.LoadUint32(x) and directly access it using *x?

like image 324
Yuguang Avatar asked Oct 04 '17 04:10

Yuguang


1 Answers

which basically load the value from the memory address and return it.

That is the case in your context, but might differ on a different machine architecture where atomicity is to be implemented, as discussed here.
As mentioned in go issue 8739

We intrinsify both sync/atomic and runtime/internal/atomic for a bunch of architectures.
The APIs are not unified (e.g. LoadUint32 in sync/atomic is Load in runtime/internal/atomic).

(* "intrinsify" as in issue 4947)

As mentioned in my first link:

Regarding loads and stores.

Memory model along with instruction set specifies whether plain loads and stores are atomic or not. Typical guarantee for all modern commodity hardware is that aligned word-sized loads and stores are atomic. For example, on x86 architecture (IA-32 and Intel 64) 1-, 2-, 4-, 8- and 16-byte aligned loads and stores are all atomic (that is, plain MOV instruction, MOVQ and MOVDQA are atomic).

like image 76
VonC Avatar answered Oct 03 '22 20:10

VonC