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
225 sz := uintptr(n * PtrSize)
226 name := fmt.Sprint(sz)
227 if backward {
228 name += "-backward"
229 } else {
230 name += "-forward"
231 }
232 t.Run(name, func(t *testing.T) {
233
234 var s [100]*int
235 src := s[n-1 : 2*n-1]
236 dst := s[:n]
237 if backward {
238 src, dst = dst, src
239 }
240 for i := range src {
241 src[i] = &x
242 }
243 clear(dst)
244
245 var ready atomic.Uint32
246 go func() {
247 sp := unsafe.Pointer(&src[0])
248 dp := unsafe.Pointer(&dst[0])
249 ready.Store(1)
250 for i := 0; i < 10000; i++ {
251 Memmove(dp, sp, sz)
252 MemclrNoHeapPointers(dp, sz)
253 }
254 ready.Store(2)
255 }()
256
257 for ready.Load() == 0 {
258 Gosched()
259 }
260
261 for ready.Load() != 2 {
262 for i := range dst {
263 p := dst[i]
264 if p != nil && p != &x {
265 t.Fatalf("got partially updated pointer %p at dst[%d], want either nil or %p", p, i, &x)
266 }
267 }
268 }
269 })
270 }
271 }
272 }
273
274 func benchmarkSizes(b *testing.B, sizes []int, fn func(b *testing.B, n int)) {
275 for _, n := range sizes {
276 b.Run(fmt.Sprint(n), func(b *testing.B) {
277 b.SetBytes(int64(n))
278 fn(b, n)
279 })
280 }
281 }
282
283 var bufSizes = []int{
284 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
285 32, 64, 128, 256, 512, 1024, 2048, 4096,
286 }
287 var bufSizesOverlap = []int{
288 32, 64, 128, 256, 512, 1024, 2048, 4096,
289 }
290
291 func BenchmarkMemmove(b *testing.B) {
292 benchmarkSizes(b, bufSizes, func(b *testing.B, n int) {
293 x := make([]byte, n)
294 y := make([]byte, n)
295 b.ResetTimer()
296 for i := 0; i < b.N; i++ {
297 copy(x, y)
298 }
299 })
300 }
301
302 func BenchmarkMemmoveOverlap(b *testing.B) {
303 benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
304 x := make([]byte, n+16)
305 b.ResetTimer()
306 for i := 0; i < b.N; i++ {
307 copy(x[16:n+16], x[:n])
308 }
309 })
310 }
311
312 func BenchmarkMemmoveUnalignedDst(b *testing.B) {
313 benchmarkSizes(b, bufSizes, func(b *testing.B, n int) {
314 x := make([]byte, n+1)
315 y := make([]byte, n)
316 b.ResetTimer()
317 for i := 0; i < b.N; i++ {
318 copy(x[1:], y)
319 }
320 })
321 }
322
323 func BenchmarkMemmoveUnalignedDstOverlap(b *testing.B) {
324 benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
325 x := make([]byte, n+16)
326 b.ResetTimer()
327 for i := 0; i < b.N; i++ {
328 copy(x[16:n+16], x[1:n+1])
329 }
330 })
331 }
332
333 func BenchmarkMemmoveUnalignedSrc(b *testing.B) {
334 benchmarkSizes(b, bufSizes, func(b *testing.B, n int) {
335 x := make([]byte, n)
336 y := make([]byte, n+1)
337 b.ResetTimer()
338 for i := 0; i < b.N; i++ {
339 copy(x, y[1:])
340 }
341 })
342 }
343
344 func BenchmarkMemmoveUnalignedSrcDst(b *testing.B) {
345 for _, n := range []int{16, 64, 256, 4096, 65536} {
346 buf := make([]byte, (n+8)*2)
347 x := buf[:len(buf)/2]
348 y := buf[len(buf)/2:]
349 for _, off := range []int{0, 1, 4, 7} {
350 b.Run(fmt.Sprint("f_", n, off), func(b *testing.B) {
351 b.SetBytes(int64(n))
352 for i := 0; i < b.N; i++ {
353 copy(x[off:n+off], y[off:n+off])
354 }
355 })
356
357 b.Run(fmt.Sprint("b_", n, off), func(b *testing.B) {
358 b.SetBytes(int64(n))
359 for i := 0; i < b.N; i++ {
360 copy(y[off:n+off], x[off:n+off])
361 }
362 })
363 }
364 }
365 }
366
367 func BenchmarkMemmoveUnalignedSrcOverlap(b *testing.B) {
368 benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
369 x := make([]byte, n+1)
370 b.ResetTimer()
371 for i := 0; i < b.N; i++ {
372 copy(x[1:n+1], x[:n])
373 }
374 })
375 }
376
377 func TestMemclr(t *testing.T) {
378 size := 512
379 if testing.Short() {
380 size = 128 + 16
381 }
382 mem := make([]byte, size)
383 for i := 0; i < size; i++ {
384 mem[i] = 0xee
385 }
386 for n := 0; n < size; n++ {
387 for x := 0; x <= size-n; x++ {
388 MemclrBytes(mem[x : x+n])
389 for i := 0; i < x; i++ {
390 if mem[i] != 0xee {
391 t.Fatalf("overwrite prefix mem[%d] = %d", i, mem[i])
392 }
393 }
394 for i := x; i < x+n; i++ {
395 if mem[i] != 0 {
396 t.Fatalf("failed clear mem[%d] = %d", i, mem[i])
397 }
398 mem[i] = 0xee
399 }
400 for i := x + n; i < size; i++ {
401 if mem[i] != 0xee {
402 t.Fatalf("overwrite suffix mem[%d] = %d", i, mem[i])
403 }
404 }
405 }
406 }
407 }
408
409 func BenchmarkMemclr(b *testing.B) {
410 for _, n := range []int{5, 16, 64, 256, 4096, 65536} {
411 x := make([]byte, n)
412 b.Run(fmt.Sprint(n), func(b *testing.B) {
413 b.SetBytes(int64(n))
414 for i := 0; i < b.N; i++ {
415 MemclrBytes(x)
416 }
417 })
418 }
419 for _, m := range []int{1, 4, 8, 16, 64} {
420 x := make([]byte, m<<20)
421 b.Run(fmt.Sprint(m, "M"), func(b *testing.B) {
422 b.SetBytes(int64(m << 20))
423 for i := 0; i < b.N; i++ {
424 MemclrBytes(x)
425 }
426 })
427 }
428 }
429
430 func BenchmarkMemclrUnaligned(b *testing.B) {
431 for _, off := range []int{0, 1, 4, 7} {
432 for _, n := range []int{5, 16, 64, 256, 4096, 65536} {
433 x := make([]byte, n+off)
434 b.Run(fmt.Sprint(off, n), func(b *testing.B) {
435 b.SetBytes(int64(n))
436 for i := 0; i < b.N; i++ {
437 MemclrBytes(x[off:])
438 }
439 })
440 }
441 }
442
443 for _, off := range []int{0, 1, 4, 7} {
444 for _, m := range []int{1, 4, 8, 16, 64} {
445 x := make([]byte, (m<<20)+off)
446 b.Run(fmt.Sprint(off, m, "M"), func(b *testing.B) {
447 b.SetBytes(int64(m << 20))
448 for i := 0; i < b.N; i++ {
449 MemclrBytes(x[off:])
450 }
451 })
452 }
453 }
454 }
455
456 func BenchmarkGoMemclr(b *testing.B) {
457 benchmarkSizes(b, []int{5, 16, 64, 256}, func(b *testing.B, n int) {
458 x := make([]byte, n)
459 b.ResetTimer()
460 for i := 0; i < b.N; i++ {
461 clear(x)
462 }
463 })
464 }
465
466 func BenchmarkMemclrRange(b *testing.B) {
467 type RunData struct {
468 data []int
469 }
470
471 benchSizes := []RunData{
472 {[]int{1043, 1078, 1894, 1582, 1044, 1165, 1467, 1100, 1919, 1562, 1932, 1645,
473 1412, 1038, 1576, 1200, 1029, 1336, 1095, 1494, 1350, 1025, 1502, 1548, 1316, 1296,
474 1868, 1639, 1546, 1626, 1642, 1308, 1726, 1665, 1678, 1187, 1515, 1598, 1353, 1237,
475 1977, 1452, 2012, 1914, 1514, 1136, 1975, 1618, 1536, 1695, 1600, 1733, 1392, 1099,
476 1358, 1996, 1224, 1783, 1197, 1838, 1460, 1556, 1554, 2020}},
477 {[]int{3964, 5139, 6573, 7775, 6553, 2413, 3466, 5394, 2469, 7336, 7091, 6745,
478 4028, 5643, 6164, 3475, 4138, 6908, 7559, 3335, 5660, 4122, 3945, 2082, 7564, 6584,
479 5111, 2288, 6789, 2797, 4928, 7986, 5163, 5447, 2999, 4968, 3174, 3202, 7908, 8137,
480 4735, 6161, 4646, 7592, 3083, 5329, 3687, 2754, 3599, 7231, 6455, 2549, 8063, 2189,
481 7121, 5048, 4277, 6626, 6306, 2815, 7473, 3963, 7549, 7255}},
482 {[]int{16304, 15936, 15760, 4736, 9136, 11184, 10160, 5952, 14560, 15744,
483 6624, 5872, 13088, 14656, 14192, 10304, 4112, 10384, 9344, 4496, 11392, 7024,
484 5200, 10064, 14784, 5808, 13504, 10480, 8512, 4896, 13264, 5600}},
485 {[]int{164576, 233136, 220224, 183280, 214112, 217248, 228560, 201728}},
486 }
487
488 for _, t := range benchSizes {
489 total := 0
490 minLen := 0
491 maxLen := 0
492
493 for _, clrLen := range t.data {
494 maxLen = max(maxLen, clrLen)
495 if clrLen < minLen || minLen == 0 {
496 minLen = clrLen
497 }
498 total += clrLen
499 }
500 buffer := make([]byte, maxLen)
501
502 text := ""
503 if minLen >= (1 << 20) {
504 text = fmt.Sprint(minLen>>20, "M ", (maxLen+(1<<20-1))>>20, "M")
505 } else if minLen >= (1 << 10) {
506 text = fmt.Sprint(minLen>>10, "K ", (maxLen+(1<<10-1))>>10, "K")
507 } else {
508 text = fmt.Sprint(minLen, " ", maxLen)
509 }
510 b.Run(text, func(b *testing.B) {
511 b.SetBytes(int64(total))
512 for i := 0; i < b.N; i++ {
513 for _, clrLen := range t.data {
514 MemclrBytes(buffer[:clrLen])
515 }
516 }
517 })
518 }
519 }
520
521 func BenchmarkClearFat3(b *testing.B) {
522 p := new([3]byte)
523 Escape(p)
524 b.ResetTimer()
525 for i := 0; i < b.N; i++ {
526 *p = [3]byte{}
527 }
528 }
529
530 func BenchmarkClearFat4(b *testing.B) {
531 p := new([4 / 4]uint32)
532 Escape(p)
533 b.ResetTimer()
534 for i := 0; i < b.N; i++ {
535 *p = [4 / 4]uint32{}
536 }
537 }
538
539 func BenchmarkClearFat5(b *testing.B) {
540 p := new([5]byte)
541 Escape(p)
542 b.ResetTimer()
543 for i := 0; i < b.N; i++ {
544 *p = [5]byte{}
545 }
546 }
547
548 func BenchmarkClearFat6(b *testing.B) {
549 p := new([6]byte)
550 Escape(p)
551 b.ResetTimer()
552 for i := 0; i < b.N; i++ {
553 *p = [6]byte{}
554 }
555 }
556
557 func BenchmarkClearFat7(b *testing.B) {
558 p := new([7]byte)
559 Escape(p)
560 b.ResetTimer()
561 for i := 0; i < b.N; i++ {
562 *p = [7]byte{}
563 }
564 }
565
566 func BenchmarkClearFat8(b *testing.B) {
567 p := new([8 / 4]uint32)
568 Escape(p)
569 b.ResetTimer()
570 for i := 0; i < b.N; i++ {
571 *p = [8 / 4]uint32{}
572 }
573 }
574
575 func BenchmarkClearFat9(b *testing.B) {
576 p := new([9]byte)
577 Escape(p)
578 b.ResetTimer()
579 for i := 0; i < b.N; i++ {
580 *p = [9]byte{}
581 }
582 }
583
584 func BenchmarkClearFat10(b *testing.B) {
585 p := new([10]byte)
586 Escape(p)
587 b.ResetTimer()
588 for i := 0; i < b.N; i++ {
589 *p = [10]byte{}
590 }
591 }
592
593 func BenchmarkClearFat11(b *testing.B) {
594 p := new([11]byte)
595 Escape(p)
596 b.ResetTimer()
597 for i := 0; i < b.N; i++ {
598 *p = [11]byte{}
599 }
600 }
601
602 func BenchmarkClearFat12(b *testing.B) {
603 p := new([12 / 4]uint32)
604 Escape(p)
605 b.ResetTimer()
606 for i := 0; i < b.N; i++ {
607 *p = [12 / 4]uint32{}
608 }
609 }
610
611 func BenchmarkClearFat13(b *testing.B) {
612 p := new([13]byte)
613 Escape(p)
614 b.ResetTimer()
615 for i := 0; i < b.N; i++ {
616 *p = [13]byte{}
617 }
618 }
619
620 func BenchmarkClearFat14(b *testing.B) {
621 p := new([14]byte)
622 Escape(p)
623 b.ResetTimer()
624 for i := 0; i < b.N; i++ {
625 *p = [14]byte{}
626 }
627 }
628
629 func BenchmarkClearFat15(b *testing.B) {
630 p := new([15]byte)
631 Escape(p)
632 b.ResetTimer()
633 for i := 0; i < b.N; i++ {
634 *p = [15]byte{}
635 }
636 }
637
638 func BenchmarkClearFat16(b *testing.B) {
639 p := new([16 / 4]uint32)
640 Escape(p)
641 b.ResetTimer()
642 for i := 0; i < b.N; i++ {
643 *p = [16 / 4]uint32{}
644 }
645 }
646
647 func BenchmarkClearFat18(b *testing.B) {
648 p := new([18]byte)
649 Escape(p)
650 b.ResetTimer()
651 for i := 0; i < b.N; i++ {
652 *p = [18]byte{}
653 }
654 }
655
656 func BenchmarkClearFat20(b *testing.B) {
657 p := new([20 / 4]uint32)
658 Escape(p)
659 b.ResetTimer()
660 for i := 0; i < b.N; i++ {
661 *p = [20 / 4]uint32{}
662 }
663 }
664
665 func BenchmarkClearFat24(b *testing.B) {
666 p := new([24 / 4]uint32)
667 Escape(p)
668 b.ResetTimer()
669 for i := 0; i < b.N; i++ {
670 *p = [24 / 4]uint32{}
671 }
672 }
673
674 func BenchmarkClearFat32(b *testing.B) {
675 p := new([32 / 4]uint32)
676 Escape(p)
677 b.ResetTimer()
678 for i := 0; i < b.N; i++ {
679 *p = [32 / 4]uint32{}
680 }
681 }
682
683 func BenchmarkClearFat40(b *testing.B) {
684 p := new([40 / 4]uint32)
685 Escape(p)
686 b.ResetTimer()
687 for i := 0; i < b.N; i++ {
688 *p = [40 / 4]uint32{}
689 }
690 }
691
692 func BenchmarkClearFat48(b *testing.B) {
693 p := new([48 / 4]uint32)
694 Escape(p)
695 b.ResetTimer()
696 for i := 0; i < b.N; i++ {
697 *p = [48 / 4]uint32{}
698 }
699 }
700
701 func BenchmarkClearFat56(b *testing.B) {
702 p := new([56 / 4]uint32)
703 Escape(p)
704 b.ResetTimer()
705 for i := 0; i < b.N; i++ {
706 *p = [56 / 4]uint32{}
707 }
708 }
709
710 func BenchmarkClearFat64(b *testing.B) {
711 p := new([64 / 4]uint32)
712 Escape(p)
713 b.ResetTimer()
714 for i := 0; i < b.N; i++ {
715 *p = [64 / 4]uint32{}
716 }
717 }
718
719 func BenchmarkClearFat72(b *testing.B) {
720 p := new([72 / 4]uint32)
721 Escape(p)
722 b.ResetTimer()
723 for i := 0; i < b.N; i++ {
724 *p = [72 / 4]uint32{}
725 }
726 }
727
728 func BenchmarkClearFat128(b *testing.B) {
729 p := new([128 / 4]uint32)
730 Escape(p)
731 b.ResetTimer()
732 for i := 0; i < b.N; i++ {
733 *p = [128 / 4]uint32{}
734 }
735 }
736
737 func BenchmarkClearFat256(b *testing.B) {
738 p := new([256 / 4]uint32)
739 Escape(p)
740 b.ResetTimer()
741 for i := 0; i < b.N; i++ {
742 *p = [256 / 4]uint32{}
743 }
744 }
745
746 func BenchmarkClearFat512(b *testing.B) {
747 p := new([512 / 4]uint32)
748 Escape(p)
749 b.ResetTimer()
750 for i := 0; i < b.N; i++ {
751 *p = [512 / 4]uint32{}
752 }
753 }
754
755 func BenchmarkClearFat1024(b *testing.B) {
756 p := new([1024 / 4]uint32)
757 Escape(p)
758 b.ResetTimer()
759 for i := 0; i < b.N; i++ {
760 *p = [1024 / 4]uint32{}
761 }
762 }
763
764 func BenchmarkClearFat1032(b *testing.B) {
765 p := new([1032 / 4]uint32)
766 Escape(p)
767 b.ResetTimer()
768 for i := 0; i < b.N; i++ {
769 *p = [1032 / 4]uint32{}
770 }
771 }
772
773 func BenchmarkClearFat1040(b *testing.B) {
774 p := new([1040 / 4]uint32)
775 Escape(p)
776 b.ResetTimer()
777 for i := 0; i < b.N; i++ {
778 *p = [1040 / 4]uint32{}
779 }
780 }
781
782 func BenchmarkCopyFat3(b *testing.B) {
783 var x [3]byte
784 p := new([3]byte)
785 Escape(p)
786 b.ResetTimer()
787 for i := 0; i < b.N; i++ {
788 *p = x
789 }
790 }
791
792 func BenchmarkCopyFat4(b *testing.B) {
793 var x [4 / 4]uint32
794 p := new([4 / 4]uint32)
795 Escape(p)
796 b.ResetTimer()
797 for i := 0; i < b.N; i++ {
798 *p = x
799 }
800 }
801
802 func BenchmarkCopyFat5(b *testing.B) {
803 var x [5]byte
804 p := new([5]byte)
805 Escape(p)
806 b.ResetTimer()
807 for i := 0; i < b.N; i++ {
808 *p = x
809 }
810 }
811
812 func BenchmarkCopyFat6(b *testing.B) {
813 var x [6]byte
814 p := new([6]byte)
815 Escape(p)
816 b.ResetTimer()
817 for i := 0; i < b.N; i++ {
818 *p = x
819 }
820 }
821
822 func BenchmarkCopyFat7(b *testing.B) {
823 var x [7]byte
824 p := new([7]byte)
825 Escape(p)
826 b.ResetTimer()
827 for i := 0; i < b.N; i++ {
828 *p = x
829 }
830 }
831
832 func BenchmarkCopyFat8(b *testing.B) {
833 var x [8 / 4]uint32
834 p := new([8 / 4]uint32)
835 Escape(p)
836 b.ResetTimer()
837 for i := 0; i < b.N; i++ {
838 *p = x
839 }
840 }
841
842 func BenchmarkCopyFat9(b *testing.B) {
843 var x [9]byte
844 p := new([9]byte)
845 Escape(p)
846 b.ResetTimer()
847 for i := 0; i < b.N; i++ {
848 *p = x
849 }
850 }
851
852 func BenchmarkCopyFat10(b *testing.B) {
853 var x [10]byte
854 p := new([10]byte)
855 Escape(p)
856 b.ResetTimer()
857 for i := 0; i < b.N; i++ {
858 *p = x
859 }
860 }
861
862 func BenchmarkCopyFat11(b *testing.B) {
863 var x [11]byte
864 p := new([11]byte)
865 Escape(p)
866 b.ResetTimer()
867 for i := 0; i < b.N; i++ {
868 *p = x
869 }
870 }
871
872 func BenchmarkCopyFat12(b *testing.B) {
873 var x [12 / 4]uint32
874 p := new([12 / 4]uint32)
875 Escape(p)
876 b.ResetTimer()
877 for i := 0; i < b.N; i++ {
878 *p = x
879 }
880 }
881
882 func BenchmarkCopyFat13(b *testing.B) {
883 var x [13]byte
884 p := new([13]byte)
885 Escape(p)
886 b.ResetTimer()
887 for i := 0; i < b.N; i++ {
888 *p = x
889 }
890 }
891
892 func BenchmarkCopyFat14(b *testing.B) {
893 var x [14]byte
894 p := new([14]byte)
895 Escape(p)
896 b.ResetTimer()
897 for i := 0; i < b.N; i++ {
898 *p = x
899 }
900 }
901
902 func BenchmarkCopyFat15(b *testing.B) {
903 var x [15]byte
904 p := new([15]byte)
905 Escape(p)
906 b.ResetTimer()
907 for i := 0; i < b.N; i++ {
908 *p = x
909 }
910 }
911
912 func BenchmarkCopyFat16(b *testing.B) {
913 var x [16 / 4]uint32
914 p := new([16 / 4]uint32)
915 Escape(p)
916 b.ResetTimer()
917 for i := 0; i < b.N; i++ {
918 *p = x
919 }
920 }
921
922 func BenchmarkCopyFat18(b *testing.B) {
923 var x [18]byte
924 p := new([18]byte)
925 Escape(p)
926 b.ResetTimer()
927 for i := 0; i < b.N; i++ {
928 *p = x
929 }
930 }
931
932 func BenchmarkCopyFat20(b *testing.B) {
933 var x [20 / 4]uint32
934 p := new([20 / 4]uint32)
935 Escape(p)
936 b.ResetTimer()
937 for i := 0; i < b.N; i++ {
938 *p = x
939 }
940 }
941
942 func BenchmarkCopyFat24(b *testing.B) {
943 var x [24 / 4]uint32
944 p := new([24 / 4]uint32)
945 Escape(p)
946 b.ResetTimer()
947 for i := 0; i < b.N; i++ {
948 *p = x
949 }
950 }
951
952 func BenchmarkCopyFat32(b *testing.B) {
953 var x [32 / 4]uint32
954 p := new([32 / 4]uint32)
955 Escape(p)
956 b.ResetTimer()
957 for i := 0; i < b.N; i++ {
958 *p = x
959 }
960 }
961
962 func BenchmarkCopyFat64(b *testing.B) {
963 var x [64 / 4]uint32
964 p := new([64 / 4]uint32)
965 Escape(p)
966 b.ResetTimer()
967 for i := 0; i < b.N; i++ {
968 *p = x
969 }
970 }
971
972 func BenchmarkCopyFat72(b *testing.B) {
973 var x [72 / 4]uint32
974 p := new([72 / 4]uint32)
975 Escape(p)
976 b.ResetTimer()
977 for i := 0; i < b.N; i++ {
978 *p = x
979 }
980 }
981
982 func BenchmarkCopyFat128(b *testing.B) {
983 var x [128 / 4]uint32
984 p := new([128 / 4]uint32)
985 Escape(p)
986 b.ResetTimer()
987 for i := 0; i < b.N; i++ {
988 *p = x
989 }
990 }
991
992 func BenchmarkCopyFat256(b *testing.B) {
993 var x [256 / 4]uint32
994 p := new([256 / 4]uint32)
995 Escape(p)
996 b.ResetTimer()
997 for i := 0; i < b.N; i++ {
998 *p = x
999 }
1000 }
1001
1002 func BenchmarkCopyFat512(b *testing.B) {
1003 var x [512 / 4]uint32
1004 p := new([512 / 4]uint32)
1005 Escape(p)
1006 b.ResetTimer()
1007 for i := 0; i < b.N; i++ {
1008 *p = x
1009 }
1010 }
1011
1012 func BenchmarkCopyFat520(b *testing.B) {
1013 var x [520 / 4]uint32
1014 p := new([520 / 4]uint32)
1015 Escape(p)
1016 b.ResetTimer()
1017 for i := 0; i < b.N; i++ {
1018 *p = x
1019 }
1020 }
1021
1022 func BenchmarkCopyFat1024(b *testing.B) {
1023 var x [1024 / 4]uint32
1024 p := new([1024 / 4]uint32)
1025 Escape(p)
1026 b.ResetTimer()
1027 for i := 0; i < b.N; i++ {
1028 *p = x
1029 }
1030 }
1031
1032 func BenchmarkCopyFat1032(b *testing.B) {
1033 var x [1032 / 4]uint32
1034 p := new([1032 / 4]uint32)
1035 Escape(p)
1036 b.ResetTimer()
1037 for i := 0; i < b.N; i++ {
1038 *p = x
1039 }
1040 }
1041
1042 func BenchmarkCopyFat1040(b *testing.B) {
1043 var x [1040 / 4]uint32
1044 p := new([1040 / 4]uint32)
1045 Escape(p)
1046 b.ResetTimer()
1047 for i := 0; i < b.N; i++ {
1048 *p = x
1049 }
1050 }
1051
1052
1053
1054
1055 func BenchmarkIssue18740(b *testing.B) {
1056 benchmarks := []struct {
1057 name string
1058 nbyte int
1059 f func([]byte) uint64
1060 }{
1061 {"2byte", 2, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint16(buf)) }},
1062 {"4byte", 4, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint32(buf)) }},
1063 {"8byte", 8, func(buf []byte) uint64 { return binary.LittleEndian.Uint64(buf) }},
1064 }
1065
1066 var g [4096]byte
1067 for _, bm := range benchmarks {
1068 buf := make([]byte, bm.nbyte)
1069 b.Run(bm.name, func(b *testing.B) {
1070 for j := 0; j < b.N; j++ {
1071 for i := 0; i < 4096; i += bm.nbyte {
1072 copy(buf[:], g[i:])
1073 sink += bm.f(buf[:])
1074 }
1075 }
1076 })
1077 }
1078 }
1079
1080 var memclrSink []int8
1081
1082 func BenchmarkMemclrKnownSize1(b *testing.B) {
1083 var x [1]int8
1084
1085 b.SetBytes(1)
1086 for i := 0; i < b.N; i++ {
1087 for a := range x {
1088 x[a] = 0
1089 }
1090 }
1091
1092 memclrSink = x[:]
1093 }
1094 func BenchmarkMemclrKnownSize2(b *testing.B) {
1095 var x [2]int8
1096
1097 b.SetBytes(2)
1098 for i := 0; i < b.N; i++ {
1099 for a := range x {
1100 x[a] = 0
1101 }
1102 }
1103
1104 memclrSink = x[:]
1105 }
1106 func BenchmarkMemclrKnownSize4(b *testing.B) {
1107 var x [4]int8
1108
1109 b.SetBytes(4)
1110 for i := 0; i < b.N; i++ {
1111 for a := range x {
1112 x[a] = 0
1113 }
1114 }
1115
1116 memclrSink = x[:]
1117 }
1118 func BenchmarkMemclrKnownSize8(b *testing.B) {
1119 var x [8]int8
1120
1121 b.SetBytes(8)
1122 for i := 0; i < b.N; i++ {
1123 for a := range x {
1124 x[a] = 0
1125 }
1126 }
1127
1128 memclrSink = x[:]
1129 }
1130 func BenchmarkMemclrKnownSize16(b *testing.B) {
1131 var x [16]int8
1132
1133 b.SetBytes(16)
1134 for i := 0; i < b.N; i++ {
1135 for a := range x {
1136 x[a] = 0
1137 }
1138 }
1139
1140 memclrSink = x[:]
1141 }
1142 func BenchmarkMemclrKnownSize32(b *testing.B) {
1143 var x [32]int8
1144
1145 b.SetBytes(32)
1146 for i := 0; i < b.N; i++ {
1147 for a := range x {
1148 x[a] = 0
1149 }
1150 }
1151
1152 memclrSink = x[:]
1153 }
1154 func BenchmarkMemclrKnownSize64(b *testing.B) {
1155 var x [64]int8
1156
1157 b.SetBytes(64)
1158 for i := 0; i < b.N; i++ {
1159 for a := range x {
1160 x[a] = 0
1161 }
1162 }
1163
1164 memclrSink = x[:]
1165 }
1166 func BenchmarkMemclrKnownSize112(b *testing.B) {
1167 var x [112]int8
1168
1169 b.SetBytes(112)
1170 for i := 0; i < b.N; i++ {
1171 for a := range x {
1172 x[a] = 0
1173 }
1174 }
1175
1176 memclrSink = x[:]
1177 }
1178
1179 func BenchmarkMemclrKnownSize128(b *testing.B) {
1180 var x [128]int8
1181
1182 b.SetBytes(128)
1183 for i := 0; i < b.N; i++ {
1184 for a := range x {
1185 x[a] = 0
1186 }
1187 }
1188
1189 memclrSink = x[:]
1190 }
1191
1192 func BenchmarkMemclrKnownSize192(b *testing.B) {
1193 var x [192]int8
1194
1195 b.SetBytes(192)
1196 for i := 0; i < b.N; i++ {
1197 for a := range x {
1198 x[a] = 0
1199 }
1200 }
1201
1202 memclrSink = x[:]
1203 }
1204
1205 func BenchmarkMemclrKnownSize248(b *testing.B) {
1206 var x [248]int8
1207
1208 b.SetBytes(248)
1209 for i := 0; i < b.N; i++ {
1210 for a := range x {
1211 x[a] = 0
1212 }
1213 }
1214
1215 memclrSink = x[:]
1216 }
1217
1218 func BenchmarkMemclrKnownSize256(b *testing.B) {
1219 var x [256]int8
1220
1221 b.SetBytes(256)
1222 for i := 0; i < b.N; i++ {
1223 for a := range x {
1224 x[a] = 0
1225 }
1226 }
1227
1228 memclrSink = x[:]
1229 }
1230 func BenchmarkMemclrKnownSize512(b *testing.B) {
1231 var x [512]int8
1232
1233 b.SetBytes(512)
1234 for i := 0; i < b.N; i++ {
1235 for a := range x {
1236 x[a] = 0
1237 }
1238 }
1239
1240 memclrSink = x[:]
1241 }
1242 func BenchmarkMemclrKnownSize1024(b *testing.B) {
1243 var x [1024]int8
1244
1245 b.SetBytes(1024)
1246 for i := 0; i < b.N; i++ {
1247 for a := range x {
1248 x[a] = 0
1249 }
1250 }
1251
1252 memclrSink = x[:]
1253 }
1254 func BenchmarkMemclrKnownSize4096(b *testing.B) {
1255 var x [4096]int8
1256
1257 b.SetBytes(4096)
1258 for i := 0; i < b.N; i++ {
1259 for a := range x {
1260 x[a] = 0
1261 }
1262 }
1263
1264 memclrSink = x[:]
1265 }
1266 func BenchmarkMemclrKnownSize512KiB(b *testing.B) {
1267 var x [524288]int8
1268
1269 b.SetBytes(524288)
1270 for i := 0; i < b.N; i++ {
1271 for a := range x {
1272 x[a] = 0
1273 }
1274 }
1275
1276 memclrSink = x[:]
1277 }
1278
1279 func BenchmarkMemmoveKnownSize112(b *testing.B) {
1280 type T struct {
1281 x [112]int8
1282 }
1283 p := &T{}
1284 q := &T{}
1285
1286 b.SetBytes(int64(unsafe.Sizeof(T{})))
1287 for i := 0; i < b.N; i++ {
1288 *p = *q
1289 }
1290
1291 memclrSink = p.x[:]
1292 }
1293 func BenchmarkMemmoveKnownSize128(b *testing.B) {
1294 type T struct {
1295 x [128]int8
1296 }
1297 p := &T{}
1298 q := &T{}
1299
1300 b.SetBytes(int64(unsafe.Sizeof(T{})))
1301 for i := 0; i < b.N; i++ {
1302 *p = *q
1303 }
1304
1305 memclrSink = p.x[:]
1306 }
1307 func BenchmarkMemmoveKnownSize192(b *testing.B) {
1308 type T struct {
1309 x [192]int8
1310 }
1311 p := &T{}
1312 q := &T{}
1313
1314 b.SetBytes(int64(unsafe.Sizeof(T{})))
1315 for i := 0; i < b.N; i++ {
1316 *p = *q
1317 }
1318
1319 memclrSink = p.x[:]
1320 }
1321 func BenchmarkMemmoveKnownSize248(b *testing.B) {
1322 type T struct {
1323 x [248]int8
1324 }
1325 p := &T{}
1326 q := &T{}
1327
1328 b.SetBytes(int64(unsafe.Sizeof(T{})))
1329 for i := 0; i < b.N; i++ {
1330 *p = *q
1331 }
1332
1333 memclrSink = p.x[:]
1334 }
1335 func BenchmarkMemmoveKnownSize256(b *testing.B) {
1336 type T struct {
1337 x [256]int8
1338 }
1339 p := &T{}
1340 q := &T{}
1341
1342 b.SetBytes(int64(unsafe.Sizeof(T{})))
1343 for i := 0; i < b.N; i++ {
1344 *p = *q
1345 }
1346
1347 memclrSink = p.x[:]
1348 }
1349 func BenchmarkMemmoveKnownSize512(b *testing.B) {
1350 type T struct {
1351 x [512]int8
1352 }
1353 p := &T{}
1354 q := &T{}
1355
1356 b.SetBytes(int64(unsafe.Sizeof(T{})))
1357 for i := 0; i < b.N; i++ {
1358 *p = *q
1359 }
1360
1361 memclrSink = p.x[:]
1362 }
1363 func BenchmarkMemmoveKnownSize1024(b *testing.B) {
1364 type T struct {
1365 x [1024]int8
1366 }
1367 p := &T{}
1368 q := &T{}
1369
1370 b.SetBytes(int64(unsafe.Sizeof(T{})))
1371 for i := 0; i < b.N; i++ {
1372 *p = *q
1373 }
1374
1375 memclrSink = p.x[:]
1376 }
1377
View as plain text