Source file
src/runtime/memmove_test.go
1
2
3
4
5 package runtime_test
6
7 import (
8 "crypto/rand"
9 "encoding/binary"
10 "fmt"
11 "internal/asan"
12 "internal/msan"
13 "internal/race"
14 "internal/testenv"
15 . "runtime"
16 "sync/atomic"
17 "testing"
18 "unsafe"
19 )
20
21 func TestMemmove(t *testing.T) {
22 if *flagQuick {
23 t.Skip("-quick")
24 }
25 t.Parallel()
26 size := 256
27 if testing.Short() {
28 size = 128 + 16
29 }
30 src := make([]byte, size)
31 dst := make([]byte, size)
32 for i := 0; i < size; i++ {
33 src[i] = byte(128 + (i & 127))
34 }
35 for i := 0; i < size; i++ {
36 dst[i] = byte(i & 127)
37 }
38 for n := 0; n <= size; n++ {
39 for x := 0; x <= size-n; x++ {
40 for y := 0; y <= size-n; y++ {
41 copy(dst[y:y+n], src[x:x+n])
42 for i := 0; i < y; i++ {
43 if dst[i] != byte(i&127) {
44 t.Fatalf("prefix dst[%d] = %d", i, dst[i])
45 }
46 }
47 for i := y; i < y+n; i++ {
48 if dst[i] != byte(128+((i-y+x)&127)) {
49 t.Fatalf("copied dst[%d] = %d", i, dst[i])
50 }
51 dst[i] = byte(i & 127)
52 }
53 for i := y + n; i < size; i++ {
54 if dst[i] != byte(i&127) {
55 t.Fatalf("suffix dst[%d] = %d", i, dst[i])
56 }
57 }
58 }
59 }
60 }
61 }
62
63 func TestMemmoveAlias(t *testing.T) {
64 if *flagQuick {
65 t.Skip("-quick")
66 }
67 t.Parallel()
68 size := 256
69 if testing.Short() {
70 size = 128 + 16
71 }
72 buf := make([]byte, size)
73 for i := 0; i < size; i++ {
74 buf[i] = byte(i)
75 }
76 for n := 0; n <= size; n++ {
77 for x := 0; x <= size-n; x++ {
78 for y := 0; y <= size-n; y++ {
79 copy(buf[y:y+n], buf[x:x+n])
80 for i := 0; i < y; i++ {
81 if buf[i] != byte(i) {
82 t.Fatalf("prefix buf[%d] = %d", i, buf[i])
83 }
84 }
85 for i := y; i < y+n; i++ {
86 if buf[i] != byte(i-y+x) {
87 t.Fatalf("copied buf[%d] = %d", i, buf[i])
88 }
89 buf[i] = byte(i)
90 }
91 for i := y + n; i < size; i++ {
92 if buf[i] != byte(i) {
93 t.Fatalf("suffix buf[%d] = %d", i, buf[i])
94 }
95 }
96 }
97 }
98 }
99 }
100
101 func TestMemmoveLarge0x180000(t *testing.T) {
102 if testing.Short() && testenv.Builder() == "" {
103 t.Skip("-short")
104 }
105
106 t.Parallel()
107 if race.Enabled || asan.Enabled || msan.Enabled {
108 t.Skip("skipping large memmove test under sanitizers")
109 }
110 testSize(t, 0x180000)
111 }
112
113 func TestMemmoveOverlapLarge0x120000(t *testing.T) {
114 if testing.Short() && testenv.Builder() == "" {
115 t.Skip("-short")
116 }
117
118 t.Parallel()
119 if race.Enabled || asan.Enabled || msan.Enabled {
120 t.Skip("skipping large memmove test under sanitizers")
121 }
122 testOverlap(t, 0x120000)
123 }
124
125 func testSize(t *testing.T, size int) {
126 src := make([]byte, size)
127 dst := make([]byte, size)
128 _, _ = rand.Read(src)
129 _, _ = rand.Read(dst)
130
131 ref := make([]byte, size)
132 copyref(ref, dst)
133
134 for n := size - 50; n > 1; n >>= 1 {
135 for x := 0; x <= size-n; x = x*7 + 1 {
136 for y := 0; y <= size-n; y = y*9 + 1 {
137 copy(dst[y:y+n], src[x:x+n])
138 copyref(ref[y:y+n], src[x:x+n])
139 p := cmpb(dst, ref)
140 if p >= 0 {
141 t.Fatalf("Copy failed, copying from src[%d:%d] to dst[%d:%d].\nOffset %d is different, %v != %v", x, x+n, y, y+n, p, dst[p], ref[p])
142 }
143 }
144 }
145 }
146 }
147
148 func testOverlap(t *testing.T, size int) {
149 src := make([]byte, size)
150 test := make([]byte, size)
151 ref := make([]byte, size)
152 _, _ = rand.Read(src)
153
154 for n := size - 50; n > 1; n >>= 1 {
155 for x := 0; x <= size-n; x = x*7 + 1 {
156 for y := 0; y <= size-n; y = y*9 + 1 {
157
158 copyref(test, src)
159 copyref(ref, src)
160 copy(test[y:y+n], test[x:x+n])
161 if y <= x {
162 copyref(ref[y:y+n], ref[x:x+n])
163 } else {
164 copybw(ref[y:y+n], ref[x:x+n])
165 }
166 p := cmpb(test, ref)
167 if p >= 0 {
168 t.Fatalf("Copy failed, copying from src[%d:%d] to dst[%d:%d].\nOffset %d is different, %v != %v", x, x+n, y, y+n, p, test[p], ref[p])
169 }
170 }
171 }
172 }
173
174 }
175
176
177 func copyref(dst, src []byte) {
178 for i, v := range src {
179 dst[i] = v
180 }
181 }
182
183
184 func copybw(dst, src []byte) {
185 if len(src) == 0 {
186 return
187 }
188 for i := len(src) - 1; i >= 0; i-- {
189 dst[i] = src[i]
190 }
191 }
192
193
194 func matchLen(a, b []byte, max int) int {
195 a = a[:max]
196 b = b[:max]
197 for i, av := range a {
198 if b[i] != av {
199 return i
200 }
201 }
202 return max
203 }
204
205 func cmpb(a, b []byte) int {
206 l := matchLen(a, b, len(a))
207 if l == len(a) {
208 return -1
209 }
210 return l
211 }
212
213
214
215 func TestMemmoveAtomicity(t *testing.T) {
216 if race.Enabled {
217 t.Skip("skip under the race detector -- this test is intentionally racy")
218 }
219
220 var x int
221
222 for _, backward := range []bool{true, false} {
223 for _, n := range []int{3, 4, 5, 6, 7, 8, 9, 10, 15, 25, 49} {
224 n := n
225
226
227 sz := uintptr(n * PtrSize)
228 name := fmt.Sprint(sz)
229 if backward {
230 name += "-backward"
231 } else {
232 name += "-forward"
233 }
234 t.Run(name, func(t *testing.T) {
235
236 var s [100]*int
237 src := s[n-1 : 2*n-1]
238 dst := s[:n]
239 if backward {
240 src, dst = dst, src
241 }
242 for i := range src {
243 src[i] = &x
244 }
245 clear(dst)
246
247 var ready atomic.Uint32
248 go func() {
249 sp := unsafe.Pointer(&src[0])
250 dp := unsafe.Pointer(&dst[0])
251 ready.Store(1)
252 for i := 0; i < 10000; i++ {
253 Memmove(dp, sp, sz)
254 MemclrNoHeapPointers(dp, sz)
255 }
256 ready.Store(2)
257 }()
258
259 for ready.Load() == 0 {
260 Gosched()
261 }
262
263 for ready.Load() != 2 {
264 for i := range dst {
265 p := dst[i]
266 if p != nil && p != &x {
267 t.Fatalf("got partially updated pointer %p at dst[%d], want either nil or %p", p, i, &x)
268 }
269 }
270 }
271 })
272 }
273 }
274 }
275
276 func benchmarkSizes(b *testing.B, sizes []int, fn func(b *testing.B, n int)) {
277 for _, n := range sizes {
278 b.Run(fmt.Sprint(n), func(b *testing.B) {
279 b.SetBytes(int64(n))
280 fn(b, n)
281 })
282 }
283 }
284
285 var bufSizes = []int{
286 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
287 32, 64, 128, 256, 512, 1024, 2048, 4096,
288 }
289 var bufSizesOverlap = []int{
290 32, 64, 128, 256, 512, 1024, 2048, 4096,
291 }
292
293 func BenchmarkMemmove(b *testing.B) {
294 benchmarkSizes(b, bufSizes, func(b *testing.B, n int) {
295 x := make([]byte, n)
296 y := make([]byte, n)
297 b.ResetTimer()
298 for i := 0; i < b.N; i++ {
299 copy(x, y)
300 }
301 })
302 }
303
304 func BenchmarkMemmoveOverlap(b *testing.B) {
305 benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
306 x := make([]byte, n+16)
307 b.ResetTimer()
308 for i := 0; i < b.N; i++ {
309 copy(x[16:n+16], x[:n])
310 }
311 })
312 }
313
314 func BenchmarkMemmoveUnalignedDst(b *testing.B) {
315 benchmarkSizes(b, bufSizes, func(b *testing.B, n int) {
316 x := make([]byte, n+1)
317 y := make([]byte, n)
318 b.ResetTimer()
319 for i := 0; i < b.N; i++ {
320 copy(x[1:], y)
321 }
322 })
323 }
324
325 func BenchmarkMemmoveUnalignedDstOverlap(b *testing.B) {
326 benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
327 x := make([]byte, n+16)
328 b.ResetTimer()
329 for i := 0; i < b.N; i++ {
330 copy(x[16:n+16], x[1:n+1])
331 }
332 })
333 }
334
335 func BenchmarkMemmoveUnalignedSrc(b *testing.B) {
336 benchmarkSizes(b, bufSizes, func(b *testing.B, n int) {
337 x := make([]byte, n)
338 y := make([]byte, n+1)
339 b.ResetTimer()
340 for i := 0; i < b.N; i++ {
341 copy(x, y[1:])
342 }
343 })
344 }
345
346 func BenchmarkMemmoveUnalignedSrcDst(b *testing.B) {
347 for _, n := range []int{16, 64, 256, 4096, 65536} {
348 buf := make([]byte, (n+8)*2)
349 x := buf[:len(buf)/2]
350 y := buf[len(buf)/2:]
351 for _, off := range []int{0, 1, 4, 7} {
352 b.Run(fmt.Sprint("f_", n, off), func(b *testing.B) {
353 b.SetBytes(int64(n))
354 for i := 0; i < b.N; i++ {
355 copy(x[off:n+off], y[off:n+off])
356 }
357 })
358
359 b.Run(fmt.Sprint("b_", n, off), func(b *testing.B) {
360 b.SetBytes(int64(n))
361 for i := 0; i < b.N; i++ {
362 copy(y[off:n+off], x[off:n+off])
363 }
364 })
365 }
366 }
367 }
368
369 func BenchmarkMemmoveUnalignedSrcOverlap(b *testing.B) {
370 benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
371 x := make([]byte, n+1)
372 b.ResetTimer()
373 for i := 0; i < b.N; i++ {
374 copy(x[1:n+1], x[:n])
375 }
376 })
377 }
378
379 func TestMemclr(t *testing.T) {
380 size := 512
381 if testing.Short() {
382 size = 128 + 16
383 }
384 mem := make([]byte, size)
385 for i := 0; i < size; i++ {
386 mem[i] = 0xee
387 }
388 for n := 0; n < size; n++ {
389 for x := 0; x <= size-n; x++ {
390 MemclrBytes(mem[x : x+n])
391 for i := 0; i < x; i++ {
392 if mem[i] != 0xee {
393 t.Fatalf("overwrite prefix mem[%d] = %d", i, mem[i])
394 }
395 }
396 for i := x; i < x+n; i++ {
397 if mem[i] != 0 {
398 t.Fatalf("failed clear mem[%d] = %d", i, mem[i])
399 }
400 mem[i] = 0xee
401 }
402 for i := x + n; i < size; i++ {
403 if mem[i] != 0xee {
404 t.Fatalf("overwrite suffix mem[%d] = %d", i, mem[i])
405 }
406 }
407 }
408 }
409 }
410
411 func BenchmarkMemclr(b *testing.B) {
412 for _, n := range []int{5, 16, 64, 256, 4096, 65536} {
413 x := make([]byte, n)
414 b.Run(fmt.Sprint(n), func(b *testing.B) {
415 b.SetBytes(int64(n))
416 for i := 0; i < b.N; i++ {
417 MemclrBytes(x)
418 }
419 })
420 }
421 for _, m := range []int{1, 4, 8, 16, 64} {
422 x := make([]byte, m<<20)
423 b.Run(fmt.Sprint(m, "M"), func(b *testing.B) {
424 b.SetBytes(int64(m << 20))
425 for i := 0; i < b.N; i++ {
426 MemclrBytes(x)
427 }
428 })
429 }
430 }
431
432 func BenchmarkMemclrUnaligned(b *testing.B) {
433 for _, off := range []int{0, 1, 4, 7} {
434 for _, n := range []int{5, 16, 64, 256, 4096, 65536} {
435 x := make([]byte, n+off)
436 b.Run(fmt.Sprint(off, n), func(b *testing.B) {
437 b.SetBytes(int64(n))
438 for i := 0; i < b.N; i++ {
439 MemclrBytes(x[off:])
440 }
441 })
442 }
443 }
444
445 for _, off := range []int{0, 1, 4, 7} {
446 for _, m := range []int{1, 4, 8, 16, 64} {
447 x := make([]byte, (m<<20)+off)
448 b.Run(fmt.Sprint(off, m, "M"), func(b *testing.B) {
449 b.SetBytes(int64(m << 20))
450 for i := 0; i < b.N; i++ {
451 MemclrBytes(x[off:])
452 }
453 })
454 }
455 }
456 }
457
458 func BenchmarkGoMemclr(b *testing.B) {
459 benchmarkSizes(b, []int{5, 16, 64, 256}, func(b *testing.B, n int) {
460 x := make([]byte, n)
461 b.ResetTimer()
462 for i := 0; i < b.N; i++ {
463 clear(x)
464 }
465 })
466 }
467
468 func BenchmarkMemclrRange(b *testing.B) {
469 type RunData struct {
470 data []int
471 }
472
473 benchSizes := []RunData{
474 {[]int{1043, 1078, 1894, 1582, 1044, 1165, 1467, 1100, 1919, 1562, 1932, 1645,
475 1412, 1038, 1576, 1200, 1029, 1336, 1095, 1494, 1350, 1025, 1502, 1548, 1316, 1296,
476 1868, 1639, 1546, 1626, 1642, 1308, 1726, 1665, 1678, 1187, 1515, 1598, 1353, 1237,
477 1977, 1452, 2012, 1914, 1514, 1136, 1975, 1618, 1536, 1695, 1600, 1733, 1392, 1099,
478 1358, 1996, 1224, 1783, 1197, 1838, 1460, 1556, 1554, 2020}},
479 {[]int{3964, 5139, 6573, 7775, 6553, 2413, 3466, 5394, 2469, 7336, 7091, 6745,
480 4028, 5643, 6164, 3475, 4138, 6908, 7559, 3335, 5660, 4122, 3945, 2082, 7564, 6584,
481 5111, 2288, 6789, 2797, 4928, 7986, 5163, 5447, 2999, 4968, 3174, 3202, 7908, 8137,
482 4735, 6161, 4646, 7592, 3083, 5329, 3687, 2754, 3599, 7231, 6455, 2549, 8063, 2189,
483 7121, 5048, 4277, 6626, 6306, 2815, 7473, 3963, 7549, 7255}},
484 {[]int{16304, 15936, 15760, 4736, 9136, 11184, 10160, 5952, 14560, 15744,
485 6624, 5872, 13088, 14656, 14192, 10304, 4112, 10384, 9344, 4496, 11392, 7024,
486 5200, 10064, 14784, 5808, 13504, 10480, 8512, 4896, 13264, 5600}},
487 {[]int{164576, 233136, 220224, 183280, 214112, 217248, 228560, 201728}},
488 }
489
490 for _, t := range benchSizes {
491 total := 0
492 minLen := 0
493 maxLen := 0
494
495 for _, clrLen := range t.data {
496 maxLen = max(maxLen, clrLen)
497 if clrLen < minLen || minLen == 0 {
498 minLen = clrLen
499 }
500 total += clrLen
501 }
502 buffer := make([]byte, maxLen)
503
504 text := ""
505 if minLen >= (1 << 20) {
506 text = fmt.Sprint(minLen>>20, "M ", (maxLen+(1<<20-1))>>20, "M")
507 } else if minLen >= (1 << 10) {
508 text = fmt.Sprint(minLen>>10, "K ", (maxLen+(1<<10-1))>>10, "K")
509 } else {
510 text = fmt.Sprint(minLen, " ", maxLen)
511 }
512 b.Run(text, func(b *testing.B) {
513 b.SetBytes(int64(total))
514 for i := 0; i < b.N; i++ {
515 for _, clrLen := range t.data {
516 MemclrBytes(buffer[:clrLen])
517 }
518 }
519 })
520 }
521 }
522
523 func BenchmarkClearFat7(b *testing.B) {
524 p := new([7]byte)
525 Escape(p)
526 b.ResetTimer()
527 for i := 0; i < b.N; i++ {
528 *p = [7]byte{}
529 }
530 }
531
532 func BenchmarkClearFat8(b *testing.B) {
533 p := new([8 / 4]uint32)
534 Escape(p)
535 b.ResetTimer()
536 for i := 0; i < b.N; i++ {
537 *p = [8 / 4]uint32{}
538 }
539 }
540
541 func BenchmarkClearFat11(b *testing.B) {
542 p := new([11]byte)
543 Escape(p)
544 b.ResetTimer()
545 for i := 0; i < b.N; i++ {
546 *p = [11]byte{}
547 }
548 }
549
550 func BenchmarkClearFat12(b *testing.B) {
551 p := new([12 / 4]uint32)
552 Escape(p)
553 b.ResetTimer()
554 for i := 0; i < b.N; i++ {
555 *p = [12 / 4]uint32{}
556 }
557 }
558
559 func BenchmarkClearFat13(b *testing.B) {
560 p := new([13]byte)
561 Escape(p)
562 b.ResetTimer()
563 for i := 0; i < b.N; i++ {
564 *p = [13]byte{}
565 }
566 }
567
568 func BenchmarkClearFat14(b *testing.B) {
569 p := new([14]byte)
570 Escape(p)
571 b.ResetTimer()
572 for i := 0; i < b.N; i++ {
573 *p = [14]byte{}
574 }
575 }
576
577 func BenchmarkClearFat15(b *testing.B) {
578 p := new([15]byte)
579 Escape(p)
580 b.ResetTimer()
581 for i := 0; i < b.N; i++ {
582 *p = [15]byte{}
583 }
584 }
585
586 func BenchmarkClearFat16(b *testing.B) {
587 p := new([16 / 4]uint32)
588 Escape(p)
589 b.ResetTimer()
590 for i := 0; i < b.N; i++ {
591 *p = [16 / 4]uint32{}
592 }
593 }
594
595 func BenchmarkClearFat24(b *testing.B) {
596 p := new([24 / 4]uint32)
597 Escape(p)
598 b.ResetTimer()
599 for i := 0; i < b.N; i++ {
600 *p = [24 / 4]uint32{}
601 }
602 }
603
604 func BenchmarkClearFat32(b *testing.B) {
605 p := new([32 / 4]uint32)
606 Escape(p)
607 b.ResetTimer()
608 for i := 0; i < b.N; i++ {
609 *p = [32 / 4]uint32{}
610 }
611 }
612
613 func BenchmarkClearFat40(b *testing.B) {
614 p := new([40 / 4]uint32)
615 Escape(p)
616 b.ResetTimer()
617 for i := 0; i < b.N; i++ {
618 *p = [40 / 4]uint32{}
619 }
620 }
621
622 func BenchmarkClearFat48(b *testing.B) {
623 p := new([48 / 4]uint32)
624 Escape(p)
625 b.ResetTimer()
626 for i := 0; i < b.N; i++ {
627 *p = [48 / 4]uint32{}
628 }
629 }
630
631 func BenchmarkClearFat56(b *testing.B) {
632 p := new([56 / 4]uint32)
633 Escape(p)
634 b.ResetTimer()
635 for i := 0; i < b.N; i++ {
636 *p = [56 / 4]uint32{}
637 }
638 }
639
640 func BenchmarkClearFat64(b *testing.B) {
641 p := new([64 / 4]uint32)
642 Escape(p)
643 b.ResetTimer()
644 for i := 0; i < b.N; i++ {
645 *p = [64 / 4]uint32{}
646 }
647 }
648
649 func BenchmarkClearFat72(b *testing.B) {
650 p := new([72 / 4]uint32)
651 Escape(p)
652 b.ResetTimer()
653 for i := 0; i < b.N; i++ {
654 *p = [72 / 4]uint32{}
655 }
656 }
657
658 func BenchmarkClearFat128(b *testing.B) {
659 p := new([128 / 4]uint32)
660 Escape(p)
661 b.ResetTimer()
662 for i := 0; i < b.N; i++ {
663 *p = [128 / 4]uint32{}
664 }
665 }
666
667 func BenchmarkClearFat256(b *testing.B) {
668 p := new([256 / 4]uint32)
669 Escape(p)
670 b.ResetTimer()
671 for i := 0; i < b.N; i++ {
672 *p = [256 / 4]uint32{}
673 }
674 }
675
676 func BenchmarkClearFat512(b *testing.B) {
677 p := new([512 / 4]uint32)
678 Escape(p)
679 b.ResetTimer()
680 for i := 0; i < b.N; i++ {
681 *p = [512 / 4]uint32{}
682 }
683 }
684
685 func BenchmarkClearFat1024(b *testing.B) {
686 p := new([1024 / 4]uint32)
687 Escape(p)
688 b.ResetTimer()
689 for i := 0; i < b.N; i++ {
690 *p = [1024 / 4]uint32{}
691 }
692 }
693
694 func BenchmarkClearFat1032(b *testing.B) {
695 p := new([1032 / 4]uint32)
696 Escape(p)
697 b.ResetTimer()
698 for i := 0; i < b.N; i++ {
699 *p = [1032 / 4]uint32{}
700 }
701 }
702
703 func BenchmarkClearFat1040(b *testing.B) {
704 p := new([1040 / 4]uint32)
705 Escape(p)
706 b.ResetTimer()
707 for i := 0; i < b.N; i++ {
708 *p = [1040 / 4]uint32{}
709 }
710 }
711
712 func BenchmarkCopyFat7(b *testing.B) {
713 var x [7]byte
714 p := new([7]byte)
715 Escape(p)
716 b.ResetTimer()
717 for i := 0; i < b.N; i++ {
718 *p = x
719 }
720 }
721
722 func BenchmarkCopyFat8(b *testing.B) {
723 var x [8 / 4]uint32
724 p := new([8 / 4]uint32)
725 Escape(p)
726 b.ResetTimer()
727 for i := 0; i < b.N; i++ {
728 *p = x
729 }
730 }
731
732 func BenchmarkCopyFat11(b *testing.B) {
733 var x [11]byte
734 p := new([11]byte)
735 Escape(p)
736 b.ResetTimer()
737 for i := 0; i < b.N; i++ {
738 *p = x
739 }
740 }
741
742 func BenchmarkCopyFat12(b *testing.B) {
743 var x [12 / 4]uint32
744 p := new([12 / 4]uint32)
745 Escape(p)
746 b.ResetTimer()
747 for i := 0; i < b.N; i++ {
748 *p = x
749 }
750 }
751
752 func BenchmarkCopyFat13(b *testing.B) {
753 var x [13]byte
754 p := new([13]byte)
755 Escape(p)
756 b.ResetTimer()
757 for i := 0; i < b.N; i++ {
758 *p = x
759 }
760 }
761
762 func BenchmarkCopyFat14(b *testing.B) {
763 var x [14]byte
764 p := new([14]byte)
765 Escape(p)
766 b.ResetTimer()
767 for i := 0; i < b.N; i++ {
768 *p = x
769 }
770 }
771
772 func BenchmarkCopyFat15(b *testing.B) {
773 var x [15]byte
774 p := new([15]byte)
775 Escape(p)
776 b.ResetTimer()
777 for i := 0; i < b.N; i++ {
778 *p = x
779 }
780 }
781
782 func BenchmarkCopyFat16(b *testing.B) {
783 var x [16 / 4]uint32
784 p := new([16 / 4]uint32)
785 Escape(p)
786 b.ResetTimer()
787 for i := 0; i < b.N; i++ {
788 *p = x
789 }
790 }
791
792 func BenchmarkCopyFat24(b *testing.B) {
793 var x [24 / 4]uint32
794 p := new([24 / 4]uint32)
795 Escape(p)
796 b.ResetTimer()
797 for i := 0; i < b.N; i++ {
798 *p = x
799 }
800 }
801
802 func BenchmarkCopyFat32(b *testing.B) {
803 var x [32 / 4]uint32
804 p := new([32 / 4]uint32)
805 Escape(p)
806 b.ResetTimer()
807 for i := 0; i < b.N; i++ {
808 *p = x
809 }
810 }
811
812 func BenchmarkCopyFat64(b *testing.B) {
813 var x [64 / 4]uint32
814 p := new([64 / 4]uint32)
815 Escape(p)
816 b.ResetTimer()
817 for i := 0; i < b.N; i++ {
818 *p = x
819 }
820 }
821
822 func BenchmarkCopyFat72(b *testing.B) {
823 var x [72 / 4]uint32
824 p := new([72 / 4]uint32)
825 Escape(p)
826 b.ResetTimer()
827 for i := 0; i < b.N; i++ {
828 *p = x
829 }
830 }
831
832 func BenchmarkCopyFat128(b *testing.B) {
833 var x [128 / 4]uint32
834 p := new([128 / 4]uint32)
835 Escape(p)
836 b.ResetTimer()
837 for i := 0; i < b.N; i++ {
838 *p = x
839 }
840 }
841
842 func BenchmarkCopyFat256(b *testing.B) {
843 var x [256 / 4]uint32
844 p := new([256 / 4]uint32)
845 Escape(p)
846 b.ResetTimer()
847 for i := 0; i < b.N; i++ {
848 *p = x
849 }
850 }
851
852 func BenchmarkCopyFat512(b *testing.B) {
853 var x [512 / 4]uint32
854 p := new([512 / 4]uint32)
855 Escape(p)
856 b.ResetTimer()
857 for i := 0; i < b.N; i++ {
858 *p = x
859 }
860 }
861
862 func BenchmarkCopyFat520(b *testing.B) {
863 var x [520 / 4]uint32
864 p := new([520 / 4]uint32)
865 Escape(p)
866 b.ResetTimer()
867 for i := 0; i < b.N; i++ {
868 *p = x
869 }
870 }
871
872 func BenchmarkCopyFat1024(b *testing.B) {
873 var x [1024 / 4]uint32
874 p := new([1024 / 4]uint32)
875 Escape(p)
876 b.ResetTimer()
877 for i := 0; i < b.N; i++ {
878 *p = x
879 }
880 }
881
882 func BenchmarkCopyFat1032(b *testing.B) {
883 var x [1032 / 4]uint32
884 p := new([1032 / 4]uint32)
885 Escape(p)
886 b.ResetTimer()
887 for i := 0; i < b.N; i++ {
888 *p = x
889 }
890 }
891
892 func BenchmarkCopyFat1040(b *testing.B) {
893 var x [1040 / 4]uint32
894 p := new([1040 / 4]uint32)
895 Escape(p)
896 b.ResetTimer()
897 for i := 0; i < b.N; i++ {
898 *p = x
899 }
900 }
901
902
903
904
905 func BenchmarkIssue18740(b *testing.B) {
906 benchmarks := []struct {
907 name string
908 nbyte int
909 f func([]byte) uint64
910 }{
911 {"2byte", 2, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint16(buf)) }},
912 {"4byte", 4, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint32(buf)) }},
913 {"8byte", 8, func(buf []byte) uint64 { return binary.LittleEndian.Uint64(buf) }},
914 }
915
916 var g [4096]byte
917 for _, bm := range benchmarks {
918 buf := make([]byte, bm.nbyte)
919 b.Run(bm.name, func(b *testing.B) {
920 for j := 0; j < b.N; j++ {
921 for i := 0; i < 4096; i += bm.nbyte {
922 copy(buf[:], g[i:])
923 sink += bm.f(buf[:])
924 }
925 }
926 })
927 }
928 }
929
930 var memclrSink []int8
931
932 func BenchmarkMemclrKnownSize1(b *testing.B) {
933 var x [1]int8
934
935 b.SetBytes(1)
936 for i := 0; i < b.N; i++ {
937 for a := range x {
938 x[a] = 0
939 }
940 }
941
942 memclrSink = x[:]
943 }
944 func BenchmarkMemclrKnownSize2(b *testing.B) {
945 var x [2]int8
946
947 b.SetBytes(2)
948 for i := 0; i < b.N; i++ {
949 for a := range x {
950 x[a] = 0
951 }
952 }
953
954 memclrSink = x[:]
955 }
956 func BenchmarkMemclrKnownSize4(b *testing.B) {
957 var x [4]int8
958
959 b.SetBytes(4)
960 for i := 0; i < b.N; i++ {
961 for a := range x {
962 x[a] = 0
963 }
964 }
965
966 memclrSink = x[:]
967 }
968 func BenchmarkMemclrKnownSize8(b *testing.B) {
969 var x [8]int8
970
971 b.SetBytes(8)
972 for i := 0; i < b.N; i++ {
973 for a := range x {
974 x[a] = 0
975 }
976 }
977
978 memclrSink = x[:]
979 }
980 func BenchmarkMemclrKnownSize16(b *testing.B) {
981 var x [16]int8
982
983 b.SetBytes(16)
984 for i := 0; i < b.N; i++ {
985 for a := range x {
986 x[a] = 0
987 }
988 }
989
990 memclrSink = x[:]
991 }
992 func BenchmarkMemclrKnownSize32(b *testing.B) {
993 var x [32]int8
994
995 b.SetBytes(32)
996 for i := 0; i < b.N; i++ {
997 for a := range x {
998 x[a] = 0
999 }
1000 }
1001
1002 memclrSink = x[:]
1003 }
1004 func BenchmarkMemclrKnownSize64(b *testing.B) {
1005 var x [64]int8
1006
1007 b.SetBytes(64)
1008 for i := 0; i < b.N; i++ {
1009 for a := range x {
1010 x[a] = 0
1011 }
1012 }
1013
1014 memclrSink = x[:]
1015 }
1016 func BenchmarkMemclrKnownSize112(b *testing.B) {
1017 var x [112]int8
1018
1019 b.SetBytes(112)
1020 for i := 0; i < b.N; i++ {
1021 for a := range x {
1022 x[a] = 0
1023 }
1024 }
1025
1026 memclrSink = x[:]
1027 }
1028
1029 func BenchmarkMemclrKnownSize128(b *testing.B) {
1030 var x [128]int8
1031
1032 b.SetBytes(128)
1033 for i := 0; i < b.N; i++ {
1034 for a := range x {
1035 x[a] = 0
1036 }
1037 }
1038
1039 memclrSink = x[:]
1040 }
1041
1042 func BenchmarkMemclrKnownSize192(b *testing.B) {
1043 var x [192]int8
1044
1045 b.SetBytes(192)
1046 for i := 0; i < b.N; i++ {
1047 for a := range x {
1048 x[a] = 0
1049 }
1050 }
1051
1052 memclrSink = x[:]
1053 }
1054
1055 func BenchmarkMemclrKnownSize248(b *testing.B) {
1056 var x [248]int8
1057
1058 b.SetBytes(248)
1059 for i := 0; i < b.N; i++ {
1060 for a := range x {
1061 x[a] = 0
1062 }
1063 }
1064
1065 memclrSink = x[:]
1066 }
1067
1068 func BenchmarkMemclrKnownSize256(b *testing.B) {
1069 var x [256]int8
1070
1071 b.SetBytes(256)
1072 for i := 0; i < b.N; i++ {
1073 for a := range x {
1074 x[a] = 0
1075 }
1076 }
1077
1078 memclrSink = x[:]
1079 }
1080 func BenchmarkMemclrKnownSize512(b *testing.B) {
1081 var x [512]int8
1082
1083 b.SetBytes(512)
1084 for i := 0; i < b.N; i++ {
1085 for a := range x {
1086 x[a] = 0
1087 }
1088 }
1089
1090 memclrSink = x[:]
1091 }
1092 func BenchmarkMemclrKnownSize1024(b *testing.B) {
1093 var x [1024]int8
1094
1095 b.SetBytes(1024)
1096 for i := 0; i < b.N; i++ {
1097 for a := range x {
1098 x[a] = 0
1099 }
1100 }
1101
1102 memclrSink = x[:]
1103 }
1104 func BenchmarkMemclrKnownSize4096(b *testing.B) {
1105 var x [4096]int8
1106
1107 b.SetBytes(4096)
1108 for i := 0; i < b.N; i++ {
1109 for a := range x {
1110 x[a] = 0
1111 }
1112 }
1113
1114 memclrSink = x[:]
1115 }
1116 func BenchmarkMemclrKnownSize512KiB(b *testing.B) {
1117 var x [524288]int8
1118
1119 b.SetBytes(524288)
1120 for i := 0; i < b.N; i++ {
1121 for a := range x {
1122 x[a] = 0
1123 }
1124 }
1125
1126 memclrSink = x[:]
1127 }
1128
1129 func BenchmarkMemmoveKnownSize112(b *testing.B) {
1130 type T struct {
1131 x [112]int8
1132 }
1133 p := &T{}
1134 q := &T{}
1135
1136 b.SetBytes(int64(unsafe.Sizeof(T{})))
1137 for i := 0; i < b.N; i++ {
1138 *p = *q
1139 }
1140
1141 memclrSink = p.x[:]
1142 }
1143 func BenchmarkMemmoveKnownSize128(b *testing.B) {
1144 type T struct {
1145 x [128]int8
1146 }
1147 p := &T{}
1148 q := &T{}
1149
1150 b.SetBytes(int64(unsafe.Sizeof(T{})))
1151 for i := 0; i < b.N; i++ {
1152 *p = *q
1153 }
1154
1155 memclrSink = p.x[:]
1156 }
1157 func BenchmarkMemmoveKnownSize192(b *testing.B) {
1158 type T struct {
1159 x [192]int8
1160 }
1161 p := &T{}
1162 q := &T{}
1163
1164 b.SetBytes(int64(unsafe.Sizeof(T{})))
1165 for i := 0; i < b.N; i++ {
1166 *p = *q
1167 }
1168
1169 memclrSink = p.x[:]
1170 }
1171 func BenchmarkMemmoveKnownSize248(b *testing.B) {
1172 type T struct {
1173 x [248]int8
1174 }
1175 p := &T{}
1176 q := &T{}
1177
1178 b.SetBytes(int64(unsafe.Sizeof(T{})))
1179 for i := 0; i < b.N; i++ {
1180 *p = *q
1181 }
1182
1183 memclrSink = p.x[:]
1184 }
1185 func BenchmarkMemmoveKnownSize256(b *testing.B) {
1186 type T struct {
1187 x [256]int8
1188 }
1189 p := &T{}
1190 q := &T{}
1191
1192 b.SetBytes(int64(unsafe.Sizeof(T{})))
1193 for i := 0; i < b.N; i++ {
1194 *p = *q
1195 }
1196
1197 memclrSink = p.x[:]
1198 }
1199 func BenchmarkMemmoveKnownSize512(b *testing.B) {
1200 type T struct {
1201 x [512]int8
1202 }
1203 p := &T{}
1204 q := &T{}
1205
1206 b.SetBytes(int64(unsafe.Sizeof(T{})))
1207 for i := 0; i < b.N; i++ {
1208 *p = *q
1209 }
1210
1211 memclrSink = p.x[:]
1212 }
1213 func BenchmarkMemmoveKnownSize1024(b *testing.B) {
1214 type T struct {
1215 x [1024]int8
1216 }
1217 p := &T{}
1218 q := &T{}
1219
1220 b.SetBytes(int64(unsafe.Sizeof(T{})))
1221 for i := 0; i < b.N; i++ {
1222 *p = *q
1223 }
1224
1225 memclrSink = p.x[:]
1226 }
1227
View as plain text