1
+ // +build go1.7
2
+
1
3
/*
2
4
*
3
5
* Copyright 2017 gRPC authors.
21
23
package primitives_test
22
24
23
25
import (
26
+ "fmt"
24
27
"sync"
25
28
"sync/atomic"
26
29
"testing"
30
+ "time"
31
+ "unsafe"
27
32
)
28
33
29
34
func BenchmarkSelectClosed (b * testing.B ) {
@@ -76,7 +81,7 @@ func BenchmarkAtomicBool(b *testing.B) {
76
81
}
77
82
}
78
83
79
- func BenchmarkAtomicValue (b * testing.B ) {
84
+ func BenchmarkAtomicValueLoad (b * testing.B ) {
80
85
c := atomic.Value {}
81
86
c .Store (0 )
82
87
x := 0
@@ -92,6 +97,16 @@ func BenchmarkAtomicValue(b *testing.B) {
92
97
}
93
98
}
94
99
100
+ func BenchmarkAtomicValueStore (b * testing.B ) {
101
+ c := atomic.Value {}
102
+ v := 123
103
+ b .ResetTimer ()
104
+ for i := 0 ; i < b .N ; i ++ {
105
+ c .Store (v )
106
+ }
107
+ b .StopTimer ()
108
+ }
109
+
95
110
func BenchmarkMutex (b * testing.B ) {
96
111
c := sync.Mutex {}
97
112
x := 0
@@ -188,6 +203,132 @@ func BenchmarkMutexWithoutDefer(b *testing.B) {
188
203
}
189
204
}
190
205
206
+ func BenchmarkAtomicAddInt64 (b * testing.B ) {
207
+ var c int64
208
+ b .ResetTimer ()
209
+ for i := 0 ; i < b .N ; i ++ {
210
+ atomic .AddInt64 (& c , 1 )
211
+ }
212
+ b .StopTimer ()
213
+ if c != int64 (b .N ) {
214
+ b .Fatal ("error" )
215
+ }
216
+ }
217
+
218
+ func BenchmarkAtomicTimeValueStore (b * testing.B ) {
219
+ var c atomic.Value
220
+ t := time .Now ()
221
+ b .ResetTimer ()
222
+ for i := 0 ; i < b .N ; i ++ {
223
+ c .Store (t )
224
+ }
225
+ b .StopTimer ()
226
+ }
227
+
228
+ func BenchmarkAtomic16BValueStore (b * testing.B ) {
229
+ var c atomic.Value
230
+ t := struct {
231
+ a int64
232
+ b int64
233
+ }{
234
+ 123 , 123 ,
235
+ }
236
+ b .ResetTimer ()
237
+ for i := 0 ; i < b .N ; i ++ {
238
+ c .Store (t )
239
+ }
240
+ b .StopTimer ()
241
+ }
242
+
243
+ func BenchmarkAtomic32BValueStore (b * testing.B ) {
244
+ var c atomic.Value
245
+ t := struct {
246
+ a int64
247
+ b int64
248
+ c int64
249
+ d int64
250
+ }{
251
+ 123 , 123 , 123 , 123 ,
252
+ }
253
+ b .ResetTimer ()
254
+ for i := 0 ; i < b .N ; i ++ {
255
+ c .Store (t )
256
+ }
257
+ b .StopTimer ()
258
+ }
259
+
260
+ func BenchmarkAtomicPointerStore (b * testing.B ) {
261
+ t := 123
262
+ var up unsafe.Pointer
263
+ b .ResetTimer ()
264
+ for i := 0 ; i < b .N ; i ++ {
265
+ atomic .StorePointer (& up , unsafe .Pointer (& t ))
266
+ }
267
+ b .StopTimer ()
268
+ }
269
+
270
+ func BenchmarkAtomicTimePointerStore (b * testing.B ) {
271
+ t := time .Now ()
272
+ var up unsafe.Pointer
273
+ b .ResetTimer ()
274
+ for i := 0 ; i < b .N ; i ++ {
275
+ atomic .StorePointer (& up , unsafe .Pointer (& t ))
276
+ }
277
+ b .StopTimer ()
278
+ }
279
+
280
+ func BenchmarkValueStoreWithContention (b * testing.B ) {
281
+ t := 123
282
+ for _ , n := range []int {10 , 100 , 1000 , 10000 , 100000 } {
283
+ b .Run (fmt .Sprintf ("Atomic/%v" , n ), func (b * testing.B ) {
284
+ var wg sync.WaitGroup
285
+ var c atomic.Value
286
+ for i := 0 ; i < n ; i ++ {
287
+ wg .Add (1 )
288
+ go func () {
289
+ for j := 0 ; j < b .N ; j ++ {
290
+ c .Store (t )
291
+ }
292
+ wg .Done ()
293
+ }()
294
+ }
295
+ wg .Wait ()
296
+ })
297
+ b .Run (fmt .Sprintf ("AtomicStorePointer/%v" , n ), func (b * testing.B ) {
298
+ var wg sync.WaitGroup
299
+ var up unsafe.Pointer
300
+ for i := 0 ; i < n ; i ++ {
301
+ wg .Add (1 )
302
+ go func () {
303
+ for j := 0 ; j < b .N ; j ++ {
304
+ atomic .StorePointer (& up , unsafe .Pointer (& t ))
305
+ }
306
+ wg .Done ()
307
+ }()
308
+ }
309
+ wg .Wait ()
310
+ })
311
+ b .Run (fmt .Sprintf ("Mutex/%v" , n ), func (b * testing.B ) {
312
+ var wg sync.WaitGroup
313
+ var c int
314
+ mu := sync.Mutex {}
315
+ for i := 0 ; i < n ; i ++ {
316
+ wg .Add (1 )
317
+ go func () {
318
+ for j := 0 ; j < b .N ; j ++ {
319
+ mu .Lock ()
320
+ c = t
321
+ mu .Unlock ()
322
+ }
323
+ wg .Done ()
324
+ }()
325
+ }
326
+ _ = c
327
+ wg .Wait ()
328
+ })
329
+ }
330
+ }
331
+
191
332
type myFooer struct {}
192
333
193
334
func (myFooer ) Foo () {}
0 commit comments