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 BenchmarkClearFat3(b *testing.B) {
524 p := new([3]byte)
525 Escape(p)
526 b.ResetTimer()
527 for i := 0; i < b.N; i++ {
528 *p = [3]byte{}
529 }
530 }
531
532 func BenchmarkClearFat4(b *testing.B) {
533 p := new([4 / 4]uint32)
534 Escape(p)
535 b.ResetTimer()
536 for i := 0; i < b.N; i++ {
537 *p = [4 / 4]uint32{}
538 }
539 }
540
541 func BenchmarkClearFat5(b *testing.B) {
542 p := new([5]byte)
543 Escape(p)
544 b.ResetTimer()
545 for i := 0; i < b.N; i++ {
546 *p = [5]byte{}
547 }
548 }
549
550 func BenchmarkClearFat6(b *testing.B) {
551 p := new([6]byte)
552 Escape(p)
553 b.ResetTimer()
554 for i := 0; i < b.N; i++ {
555 *p = [6]byte{}
556 }
557 }
558
559 func BenchmarkClearFat7(b *testing.B) {
560 p := new([7]byte)
561 Escape(p)
562 b.ResetTimer()
563 for i := 0; i < b.N; i++ {
564 *p = [7]byte{}
565 }
566 }
567
568 func BenchmarkClearFat8(b *testing.B) {
569 p := new([8 / 4]uint32)
570 Escape(p)
571 b.ResetTimer()
572 for i := 0; i < b.N; i++ {
573 *p = [8 / 4]uint32{}
574 }
575 }
576
577 func BenchmarkClearFat9(b *testing.B) {
578 p := new([9]byte)
579 Escape(p)
580 b.ResetTimer()
581 for i := 0; i < b.N; i++ {
582 *p = [9]byte{}
583 }
584 }
585
586 func BenchmarkClearFat10(b *testing.B) {
587 p := new([10]byte)
588 Escape(p)
589 b.ResetTimer()
590 for i := 0; i < b.N; i++ {
591 *p = [10]byte{}
592 }
593 }
594
595 func BenchmarkClearFat11(b *testing.B) {
596 p := new([11]byte)
597 Escape(p)
598 b.ResetTimer()
599 for i := 0; i < b.N; i++ {
600 *p = [11]byte{}
601 }
602 }
603
604 func BenchmarkClearFat12(b *testing.B) {
605 p := new([12 / 4]uint32)
606 Escape(p)
607 b.ResetTimer()
608 for i := 0; i < b.N; i++ {
609 *p = [12 / 4]uint32{}
610 }
611 }
612
613 func BenchmarkClearFat13(b *testing.B) {
614 p := new([13]byte)
615 Escape(p)
616 b.ResetTimer()
617 for i := 0; i < b.N; i++ {
618 *p = [13]byte{}
619 }
620 }
621
622 func BenchmarkClearFat14(b *testing.B) {
623 p := new([14]byte)
624 Escape(p)
625 b.ResetTimer()
626 for i := 0; i < b.N; i++ {
627 *p = [14]byte{}
628 }
629 }
630
631 func BenchmarkClearFat15(b *testing.B) {
632 p := new([15]byte)
633 Escape(p)
634 b.ResetTimer()
635 for i := 0; i < b.N; i++ {
636 *p = [15]byte{}
637 }
638 }
639
640 func BenchmarkClearFat16(b *testing.B) {
641 p := new([16 / 4]uint32)
642 Escape(p)
643 b.ResetTimer()
644 for i := 0; i < b.N; i++ {
645 *p = [16 / 4]uint32{}
646 }
647 }
648
649 func BenchmarkClearFat18(b *testing.B) {
650 p := new([18]byte)
651 Escape(p)
652 b.ResetTimer()
653 for i := 0; i < b.N; i++ {
654 *p = [18]byte{}
655 }
656 }
657
658 func BenchmarkClearFat20(b *testing.B) {
659 p := new([20 / 4]uint32)
660 Escape(p)
661 b.ResetTimer()
662 for i := 0; i < b.N; i++ {
663 *p = [20 / 4]uint32{}
664 }
665 }
666
667 func BenchmarkClearFat24(b *testing.B) {
668 p := new([24 / 4]uint32)
669 Escape(p)
670 b.ResetTimer()
671 for i := 0; i < b.N; i++ {
672 *p = [24 / 4]uint32{}
673 }
674 }
675
676 func BenchmarkClearFat32(b *testing.B) {
677 p := new([32 / 4]uint32)
678 Escape(p)
679 b.ResetTimer()
680 for i := 0; i < b.N; i++ {
681 *p = [32 / 4]uint32{}
682 }
683 }
684
685 func BenchmarkClearFat40(b *testing.B) {
686 p := new([40 / 4]uint32)
687 Escape(p)
688 b.ResetTimer()
689 for i := 0; i < b.N; i++ {
690 *p = [40 / 4]uint32{}
691 }
692 }
693
694 func BenchmarkClearFat48(b *testing.B) {
695 p := new([48 / 4]uint32)
696 Escape(p)
697 b.ResetTimer()
698 for i := 0; i < b.N; i++ {
699 *p = [48 / 4]uint32{}
700 }
701 }
702
703 func BenchmarkClearFat56(b *testing.B) {
704 p := new([56 / 4]uint32)
705 Escape(p)
706 b.ResetTimer()
707 for i := 0; i < b.N; i++ {
708 *p = [56 / 4]uint32{}
709 }
710 }
711
712 func BenchmarkClearFat64(b *testing.B) {
713 p := new([64 / 4]uint32)
714 Escape(p)
715 b.ResetTimer()
716 for i := 0; i < b.N; i++ {
717 *p = [64 / 4]uint32{}
718 }
719 }
720
721 func BenchmarkClearFat72(b *testing.B) {
722 p := new([72 / 4]uint32)
723 Escape(p)
724 b.ResetTimer()
725 for i := 0; i < b.N; i++ {
726 *p = [72 / 4]uint32{}
727 }
728 }
729
730 func BenchmarkClearFat128(b *testing.B) {
731 p := new([128 / 4]uint32)
732 Escape(p)
733 b.ResetTimer()
734 for i := 0; i < b.N; i++ {
735 *p = [128 / 4]uint32{}
736 }
737 }
738
739 func BenchmarkClearFat256(b *testing.B) {
740 p := new([256 / 4]uint32)
741 Escape(p)
742 b.ResetTimer()
743 for i := 0; i < b.N; i++ {
744 *p = [256 / 4]uint32{}
745 }
746 }
747
748 func BenchmarkClearFat512(b *testing.B) {
749 p := new([512 / 4]uint32)
750 Escape(p)
751 b.ResetTimer()
752 for i := 0; i < b.N; i++ {
753 *p = [512 / 4]uint32{}
754 }
755 }
756
757 func BenchmarkClearFat1024(b *testing.B) {
758 p := new([1024 / 4]uint32)
759 Escape(p)
760 b.ResetTimer()
761 for i := 0; i < b.N; i++ {
762 *p = [1024 / 4]uint32{}
763 }
764 }
765
766 func BenchmarkClearFat1032(b *testing.B) {
767 p := new([1032 / 4]uint32)
768 Escape(p)
769 b.ResetTimer()
770 for i := 0; i < b.N; i++ {
771 *p = [1032 / 4]uint32{}
772 }
773 }
774
775 func BenchmarkClearFat1040(b *testing.B) {
776 p := new([1040 / 4]uint32)
777 Escape(p)
778 b.ResetTimer()
779 for i := 0; i < b.N; i++ {
780 *p = [1040 / 4]uint32{}
781 }
782 }
783
784 func BenchmarkCopyFat3(b *testing.B) {
785 var x [3]byte
786 p := new([3]byte)
787 Escape(p)
788 b.ResetTimer()
789 for i := 0; i < b.N; i++ {
790 *p = x
791 }
792 }
793
794 func BenchmarkCopyFat4(b *testing.B) {
795 var x [4 / 4]uint32
796 p := new([4 / 4]uint32)
797 Escape(p)
798 b.ResetTimer()
799 for i := 0; i < b.N; i++ {
800 *p = x
801 }
802 }
803
804 func BenchmarkCopyFat5(b *testing.B) {
805 var x [5]byte
806 p := new([5]byte)
807 Escape(p)
808 b.ResetTimer()
809 for i := 0; i < b.N; i++ {
810 *p = x
811 }
812 }
813
814 func BenchmarkCopyFat6(b *testing.B) {
815 var x [6]byte
816 p := new([6]byte)
817 Escape(p)
818 b.ResetTimer()
819 for i := 0; i < b.N; i++ {
820 *p = x
821 }
822 }
823
824 func BenchmarkCopyFat7(b *testing.B) {
825 var x [7]byte
826 p := new([7]byte)
827 Escape(p)
828 b.ResetTimer()
829 for i := 0; i < b.N; i++ {
830 *p = x
831 }
832 }
833
834 func BenchmarkCopyFat8(b *testing.B) {
835 var x [8 / 4]uint32
836 p := new([8 / 4]uint32)
837 Escape(p)
838 b.ResetTimer()
839 for i := 0; i < b.N; i++ {
840 *p = x
841 }
842 }
843
844 func BenchmarkCopyFat9(b *testing.B) {
845 var x [9]byte
846 p := new([9]byte)
847 Escape(p)
848 b.ResetTimer()
849 for i := 0; i < b.N; i++ {
850 *p = x
851 }
852 }
853
854 func BenchmarkCopyFat10(b *testing.B) {
855 var x [10]byte
856 p := new([10]byte)
857 Escape(p)
858 b.ResetTimer()
859 for i := 0; i < b.N; i++ {
860 *p = x
861 }
862 }
863
864 func BenchmarkCopyFat11(b *testing.B) {
865 var x [11]byte
866 p := new([11]byte)
867 Escape(p)
868 b.ResetTimer()
869 for i := 0; i < b.N; i++ {
870 *p = x
871 }
872 }
873
874 func BenchmarkCopyFat12(b *testing.B) {
875 var x [12 / 4]uint32
876 p := new([12 / 4]uint32)
877 Escape(p)
878 b.ResetTimer()
879 for i := 0; i < b.N; i++ {
880 *p = x
881 }
882 }
883
884 func BenchmarkCopyFat13(b *testing.B) {
885 var x [13]byte
886 p := new([13]byte)
887 Escape(p)
888 b.ResetTimer()
889 for i := 0; i < b.N; i++ {
890 *p = x
891 }
892 }
893
894 func BenchmarkCopyFat14(b *testing.B) {
895 var x [14]byte
896 p := new([14]byte)
897 Escape(p)
898 b.ResetTimer()
899 for i := 0; i < b.N; i++ {
900 *p = x
901 }
902 }
903
904 func BenchmarkCopyFat15(b *testing.B) {
905 var x [15]byte
906 p := new([15]byte)
907 Escape(p)
908 b.ResetTimer()
909 for i := 0; i < b.N; i++ {
910 *p = x
911 }
912 }
913
914 func BenchmarkCopyFat16(b *testing.B) {
915 var x [16 / 4]uint32
916 p := new([16 / 4]uint32)
917 Escape(p)
918 b.ResetTimer()
919 for i := 0; i < b.N; i++ {
920 *p = x
921 }
922 }
923
924 func BenchmarkCopyFat18(b *testing.B) {
925 var x [18]byte
926 p := new([18]byte)
927 Escape(p)
928 b.ResetTimer()
929 for i := 0; i < b.N; i++ {
930 *p = x
931 }
932 }
933
934 func BenchmarkCopyFat20(b *testing.B) {
935 var x [20 / 4]uint32
936 p := new([20 / 4]uint32)
937 Escape(p)
938 b.ResetTimer()
939 for i := 0; i < b.N; i++ {
940 *p = x
941 }
942 }
943
944 func BenchmarkCopyFat24(b *testing.B) {
945 var x [24 / 4]uint32
946 p := new([24 / 4]uint32)
947 Escape(p)
948 b.ResetTimer()
949 for i := 0; i < b.N; i++ {
950 *p = x
951 }
952 }
953
954 func BenchmarkCopyFat32(b *testing.B) {
955 var x [32 / 4]uint32
956 p := new([32 / 4]uint32)
957 Escape(p)
958 b.ResetTimer()
959 for i := 0; i < b.N; i++ {
960 *p = x
961 }
962 }
963
964 func BenchmarkCopyFat64(b *testing.B) {
965 var x [64 / 4]uint32
966 p := new([64 / 4]uint32)
967 Escape(p)
968 b.ResetTimer()
969 for i := 0; i < b.N; i++ {
970 *p = x
971 }
972 }
973
974 func BenchmarkCopyFat72(b *testing.B) {
975 var x [72 / 4]uint32
976 p := new([72 / 4]uint32)
977 Escape(p)
978 b.ResetTimer()
979 for i := 0; i < b.N; i++ {
980 *p = x
981 }
982 }
983
984 func BenchmarkCopyFat128(b *testing.B) {
985 var x [128 / 4]uint32
986 p := new([128 / 4]uint32)
987 Escape(p)
988 b.ResetTimer()
989 for i := 0; i < b.N; i++ {
990 *p = x
991 }
992 }
993
994 func BenchmarkCopyFat256(b *testing.B) {
995 var x [256 / 4]uint32
996 p := new([256 / 4]uint32)
997 Escape(p)
998 b.ResetTimer()
999 for i := 0; i < b.N; i++ {
1000 *p = x
1001 }
1002 }
1003
1004 func BenchmarkCopyFat512(b *testing.B) {
1005 var x [512 / 4]uint32
1006 p := new([512 / 4]uint32)
1007 Escape(p)
1008 b.ResetTimer()
1009 for i := 0; i < b.N; i++ {
1010 *p = x
1011 }
1012 }
1013
1014 func BenchmarkCopyFat520(b *testing.B) {
1015 var x [520 / 4]uint32
1016 p := new([520 / 4]uint32)
1017 Escape(p)
1018 b.ResetTimer()
1019 for i := 0; i < b.N; i++ {
1020 *p = x
1021 }
1022 }
1023
1024 func BenchmarkCopyFat1024(b *testing.B) {
1025 var x [1024 / 4]uint32
1026 p := new([1024 / 4]uint32)
1027 Escape(p)
1028 b.ResetTimer()
1029 for i := 0; i < b.N; i++ {
1030 *p = x
1031 }
1032 }
1033
1034 func BenchmarkCopyFat1032(b *testing.B) {
1035 var x [1032 / 4]uint32
1036 p := new([1032 / 4]uint32)
1037 Escape(p)
1038 b.ResetTimer()
1039 for i := 0; i < b.N; i++ {
1040 *p = x
1041 }
1042 }
1043
1044 func BenchmarkCopyFat1040(b *testing.B) {
1045 var x [1040 / 4]uint32
1046 p := new([1040 / 4]uint32)
1047 Escape(p)
1048 b.ResetTimer()
1049 for i := 0; i < b.N; i++ {
1050 *p = x
1051 }
1052 }
1053
1054
1055
1056
1057 func BenchmarkIssue18740(b *testing.B) {
1058 benchmarks := []struct {
1059 name string
1060 nbyte int
1061 f func([]byte) uint64
1062 }{
1063 {"2byte", 2, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint16(buf)) }},
1064 {"4byte", 4, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint32(buf)) }},
1065 {"8byte", 8, func(buf []byte) uint64 { return binary.LittleEndian.Uint64(buf) }},
1066 }
1067
1068 var g [4096]byte
1069 for _, bm := range benchmarks {
1070 buf := make([]byte, bm.nbyte)
1071 b.Run(bm.name, func(b *testing.B) {
1072 for j := 0; j < b.N; j++ {
1073 for i := 0; i < 4096; i += bm.nbyte {
1074 copy(buf[:], g[i:])
1075 sink += bm.f(buf[:])
1076 }
1077 }
1078 })
1079 }
1080 }
1081
1082 var memclrSink []int8
1083
1084 func BenchmarkMemclrKnownSize1(b *testing.B) {
1085 var x [1]int8
1086
1087 b.SetBytes(1)
1088 for i := 0; i < b.N; i++ {
1089 for a := range x {
1090 x[a] = 0
1091 }
1092 }
1093
1094 memclrSink = x[:]
1095 }
1096 func BenchmarkMemclrKnownSize2(b *testing.B) {
1097 var x [2]int8
1098
1099 b.SetBytes(2)
1100 for i := 0; i < b.N; i++ {
1101 for a := range x {
1102 x[a] = 0
1103 }
1104 }
1105
1106 memclrSink = x[:]
1107 }
1108 func BenchmarkMemclrKnownSize4(b *testing.B) {
1109 var x [4]int8
1110
1111 b.SetBytes(4)
1112 for i := 0; i < b.N; i++ {
1113 for a := range x {
1114 x[a] = 0
1115 }
1116 }
1117
1118 memclrSink = x[:]
1119 }
1120 func BenchmarkMemclrKnownSize8(b *testing.B) {
1121 var x [8]int8
1122
1123 b.SetBytes(8)
1124 for i := 0; i < b.N; i++ {
1125 for a := range x {
1126 x[a] = 0
1127 }
1128 }
1129
1130 memclrSink = x[:]
1131 }
1132 func BenchmarkMemclrKnownSize16(b *testing.B) {
1133 var x [16]int8
1134
1135 b.SetBytes(16)
1136 for i := 0; i < b.N; i++ {
1137 for a := range x {
1138 x[a] = 0
1139 }
1140 }
1141
1142 memclrSink = x[:]
1143 }
1144 func BenchmarkMemclrKnownSize32(b *testing.B) {
1145 var x [32]int8
1146
1147 b.SetBytes(32)
1148 for i := 0; i < b.N; i++ {
1149 for a := range x {
1150 x[a] = 0
1151 }
1152 }
1153
1154 memclrSink = x[:]
1155 }
1156 func BenchmarkMemclrKnownSize64(b *testing.B) {
1157 var x [64]int8
1158
1159 b.SetBytes(64)
1160 for i := 0; i < b.N; i++ {
1161 for a := range x {
1162 x[a] = 0
1163 }
1164 }
1165
1166 memclrSink = x[:]
1167 }
1168 func BenchmarkMemclrKnownSize112(b *testing.B) {
1169 var x [112]int8
1170
1171 b.SetBytes(112)
1172 for i := 0; i < b.N; i++ {
1173 for a := range x {
1174 x[a] = 0
1175 }
1176 }
1177
1178 memclrSink = x[:]
1179 }
1180
1181 func BenchmarkMemclrKnownSize128(b *testing.B) {
1182 var x [128]int8
1183
1184 b.SetBytes(128)
1185 for i := 0; i < b.N; i++ {
1186 for a := range x {
1187 x[a] = 0
1188 }
1189 }
1190
1191 memclrSink = x[:]
1192 }
1193
1194 func BenchmarkMemclrKnownSize192(b *testing.B) {
1195 var x [192]int8
1196
1197 b.SetBytes(192)
1198 for i := 0; i < b.N; i++ {
1199 for a := range x {
1200 x[a] = 0
1201 }
1202 }
1203
1204 memclrSink = x[:]
1205 }
1206
1207 func BenchmarkMemclrKnownSize248(b *testing.B) {
1208 var x [248]int8
1209
1210 b.SetBytes(248)
1211 for i := 0; i < b.N; i++ {
1212 for a := range x {
1213 x[a] = 0
1214 }
1215 }
1216
1217 memclrSink = x[:]
1218 }
1219
1220 func BenchmarkMemclrKnownSize256(b *testing.B) {
1221 var x [256]int8
1222
1223 b.SetBytes(256)
1224 for i := 0; i < b.N; i++ {
1225 for a := range x {
1226 x[a] = 0
1227 }
1228 }
1229
1230 memclrSink = x[:]
1231 }
1232 func BenchmarkMemclrKnownSize512(b *testing.B) {
1233 var x [512]int8
1234
1235 b.SetBytes(512)
1236 for i := 0; i < b.N; i++ {
1237 for a := range x {
1238 x[a] = 0
1239 }
1240 }
1241
1242 memclrSink = x[:]
1243 }
1244 func BenchmarkMemclrKnownSize1024(b *testing.B) {
1245 var x [1024]int8
1246
1247 b.SetBytes(1024)
1248 for i := 0; i < b.N; i++ {
1249 for a := range x {
1250 x[a] = 0
1251 }
1252 }
1253
1254 memclrSink = x[:]
1255 }
1256 func BenchmarkMemclrKnownSize4096(b *testing.B) {
1257 var x [4096]int8
1258
1259 b.SetBytes(4096)
1260 for i := 0; i < b.N; i++ {
1261 for a := range x {
1262 x[a] = 0
1263 }
1264 }
1265
1266 memclrSink = x[:]
1267 }
1268 func BenchmarkMemclrKnownSize512KiB(b *testing.B) {
1269 var x [524288]int8
1270
1271 b.SetBytes(524288)
1272 for i := 0; i < b.N; i++ {
1273 for a := range x {
1274 x[a] = 0
1275 }
1276 }
1277
1278 memclrSink = x[:]
1279 }
1280
1281 func BenchmarkMemmoveKnownSize112(b *testing.B) {
1282 type T struct {
1283 x [112]int8
1284 }
1285 p := &T{}
1286 q := &T{}
1287
1288 b.SetBytes(int64(unsafe.Sizeof(T{})))
1289 for i := 0; i < b.N; i++ {
1290 *p = *q
1291 }
1292
1293 memclrSink = p.x[:]
1294 }
1295 func BenchmarkMemmoveKnownSize128(b *testing.B) {
1296 type T struct {
1297 x [128]int8
1298 }
1299 p := &T{}
1300 q := &T{}
1301
1302 b.SetBytes(int64(unsafe.Sizeof(T{})))
1303 for i := 0; i < b.N; i++ {
1304 *p = *q
1305 }
1306
1307 memclrSink = p.x[:]
1308 }
1309 func BenchmarkMemmoveKnownSize192(b *testing.B) {
1310 type T struct {
1311 x [192]int8
1312 }
1313 p := &T{}
1314 q := &T{}
1315
1316 b.SetBytes(int64(unsafe.Sizeof(T{})))
1317 for i := 0; i < b.N; i++ {
1318 *p = *q
1319 }
1320
1321 memclrSink = p.x[:]
1322 }
1323 func BenchmarkMemmoveKnownSize248(b *testing.B) {
1324 type T struct {
1325 x [248]int8
1326 }
1327 p := &T{}
1328 q := &T{}
1329
1330 b.SetBytes(int64(unsafe.Sizeof(T{})))
1331 for i := 0; i < b.N; i++ {
1332 *p = *q
1333 }
1334
1335 memclrSink = p.x[:]
1336 }
1337 func BenchmarkMemmoveKnownSize256(b *testing.B) {
1338 type T struct {
1339 x [256]int8
1340 }
1341 p := &T{}
1342 q := &T{}
1343
1344 b.SetBytes(int64(unsafe.Sizeof(T{})))
1345 for i := 0; i < b.N; i++ {
1346 *p = *q
1347 }
1348
1349 memclrSink = p.x[:]
1350 }
1351 func BenchmarkMemmoveKnownSize512(b *testing.B) {
1352 type T struct {
1353 x [512]int8
1354 }
1355 p := &T{}
1356 q := &T{}
1357
1358 b.SetBytes(int64(unsafe.Sizeof(T{})))
1359 for i := 0; i < b.N; i++ {
1360 *p = *q
1361 }
1362
1363 memclrSink = p.x[:]
1364 }
1365 func BenchmarkMemmoveKnownSize1024(b *testing.B) {
1366 type T struct {
1367 x [1024]int8
1368 }
1369 p := &T{}
1370 q := &T{}
1371
1372 b.SetBytes(int64(unsafe.Sizeof(T{})))
1373 for i := 0; i < b.N; i++ {
1374 *p = *q
1375 }
1376
1377 memclrSink = p.x[:]
1378 }
1379
View as plain text