アトミック操作
サポート言語
整数などの単純な変数の値を更新するだけならば、mutex を用いるよりも効率的に処理できる ∵ mutex はプログラムの一部を逐次処理にしてしまうため
warning.icon
複数の変数を同時に更新することはできない
通常の方法で変数を更新した方が、アトミック操作で変数を更新した場合よりもはるかに高速
e.g.
通常、CPU は頻繁にアクセスする変数をキャッシュに保持し、処理を高速化する
しかし、キャッシュの容量には限りがあるため、必要に応じて変数の内容を メインメモリ に書き戻す(フラッシュ)することがある 一方アトミック操作の場合、並列で動作する他の スレッド が変数の更新を確実に確認できるようにする必要がある これを実現するために、必要に応じて メインメモリ に書き戻したり、他の CPU がキャッシュしているデータを無効化するにしたりすることがある code:go
var total = int64(0)
func BenchmarkNormal(bench *testing.B) {
for range bench.N {
total += 1
}
}
func BenchmarkAtomic(bench *testing.B) {
for range bench.N {
atomic.AddInt64(&total, 1)
}
}
結果
code:sh
$ go test -bench=. -count 3
goos: darwin
goarch: arm64
pkg: listing12_3
cpu: Apple M2 Max
BenchmarkNormal-12 538361530 1.987 ns/op
BenchmarkNormal-12 606458019 1.965 ns/op
BenchmarkNormal-12 603949323 1.975 ns/op
BenchmarkAtomic-12 308510485 3.907 ns/op
BenchmarkAtomic-12 303942386 3.967 ns/op
BenchmarkAtomic-12 307332045 3.837 ns/op
PASS
ok listing12_3 9.182s