1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package atomic_test
6
7import (
8	"internal/runtime/atomic"
9	"testing"
10)
11
12var sink any
13
14func BenchmarkAtomicLoad64(b *testing.B) {
15	var x uint64
16	sink = &x
17	for i := 0; i < b.N; i++ {
18		_ = atomic.Load64(&x)
19	}
20}
21
22func BenchmarkAtomicStore64(b *testing.B) {
23	var x uint64
24	sink = &x
25	for i := 0; i < b.N; i++ {
26		atomic.Store64(&x, 0)
27	}
28}
29
30func BenchmarkAtomicLoad(b *testing.B) {
31	var x uint32
32	sink = &x
33	for i := 0; i < b.N; i++ {
34		_ = atomic.Load(&x)
35	}
36}
37
38func BenchmarkAtomicStore(b *testing.B) {
39	var x uint32
40	sink = &x
41	for i := 0; i < b.N; i++ {
42		atomic.Store(&x, 0)
43	}
44}
45
46func BenchmarkAnd8(b *testing.B) {
47	var x [512]uint8 // give byte its own cache line
48	sink = &x
49	for i := 0; i < b.N; i++ {
50		atomic.And8(&x[255], uint8(i))
51	}
52}
53
54func BenchmarkAnd(b *testing.B) {
55	var x [128]uint32 // give x its own cache line
56	sink = &x
57	for i := 0; i < b.N; i++ {
58		atomic.And(&x[63], uint32(i))
59	}
60}
61
62func BenchmarkAnd8Parallel(b *testing.B) {
63	var x [512]uint8 // give byte its own cache line
64	sink = &x
65	b.RunParallel(func(pb *testing.PB) {
66		i := uint8(0)
67		for pb.Next() {
68			atomic.And8(&x[255], i)
69			i++
70		}
71	})
72}
73
74func BenchmarkAndParallel(b *testing.B) {
75	var x [128]uint32 // give x its own cache line
76	sink = &x
77	b.RunParallel(func(pb *testing.PB) {
78		i := uint32(0)
79		for pb.Next() {
80			atomic.And(&x[63], i)
81			i++
82		}
83	})
84}
85
86func BenchmarkOr8(b *testing.B) {
87	var x [512]uint8 // give byte its own cache line
88	sink = &x
89	for i := 0; i < b.N; i++ {
90		atomic.Or8(&x[255], uint8(i))
91	}
92}
93
94func BenchmarkOr(b *testing.B) {
95	var x [128]uint32 // give x its own cache line
96	sink = &x
97	for i := 0; i < b.N; i++ {
98		atomic.Or(&x[63], uint32(i))
99	}
100}
101
102func BenchmarkOr8Parallel(b *testing.B) {
103	var x [512]uint8 // give byte its own cache line
104	sink = &x
105	b.RunParallel(func(pb *testing.PB) {
106		i := uint8(0)
107		for pb.Next() {
108			atomic.Or8(&x[255], i)
109			i++
110		}
111	})
112}
113
114func BenchmarkOrParallel(b *testing.B) {
115	var x [128]uint32 // give x its own cache line
116	sink = &x
117	b.RunParallel(func(pb *testing.PB) {
118		i := uint32(0)
119		for pb.Next() {
120			atomic.Or(&x[63], i)
121			i++
122		}
123	})
124}
125
126func BenchmarkXadd(b *testing.B) {
127	var x uint32
128	ptr := &x
129	b.RunParallel(func(pb *testing.PB) {
130		for pb.Next() {
131			atomic.Xadd(ptr, 1)
132		}
133	})
134}
135
136func BenchmarkXadd64(b *testing.B) {
137	var x uint64
138	ptr := &x
139	b.RunParallel(func(pb *testing.PB) {
140		for pb.Next() {
141			atomic.Xadd64(ptr, 1)
142		}
143	})
144}
145
146func BenchmarkCas(b *testing.B) {
147	var x uint32
148	x = 1
149	ptr := &x
150	b.RunParallel(func(pb *testing.PB) {
151		for pb.Next() {
152			atomic.Cas(ptr, 1, 0)
153			atomic.Cas(ptr, 0, 1)
154		}
155	})
156}
157
158func BenchmarkCas64(b *testing.B) {
159	var x uint64
160	x = 1
161	ptr := &x
162	b.RunParallel(func(pb *testing.PB) {
163		for pb.Next() {
164			atomic.Cas64(ptr, 1, 0)
165			atomic.Cas64(ptr, 0, 1)
166		}
167	})
168}
169func BenchmarkXchg(b *testing.B) {
170	var x uint32
171	x = 1
172	ptr := &x
173	b.RunParallel(func(pb *testing.PB) {
174		var y uint32
175		y = 1
176		for pb.Next() {
177			y = atomic.Xchg(ptr, y)
178			y += 1
179		}
180	})
181}
182
183func BenchmarkXchg64(b *testing.B) {
184	var x uint64
185	x = 1
186	ptr := &x
187	b.RunParallel(func(pb *testing.PB) {
188		var y uint64
189		y = 1
190		for pb.Next() {
191			y = atomic.Xchg64(ptr, y)
192			y += 1
193		}
194	})
195}
196