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/race"
12 "internal/testenv"
13 . "runtime"
14 "sync/atomic"
15 "testing"
16 "unsafe"
17 )
18
19 func TestMemmove(t *testing.T) {
20 if *flagQuick {
21 t.Skip("-quick")
22 }
23 t.Parallel()
24 size := 256
25 if testing.Short() {
26 size = 128 + 16
27 }
28 src := make([]byte, size)
29 dst := make([]byte, size)
30 for i := 0; i < size; i++ {
31 src[i] = byte(128 + (i & 127))
32 }
33 for i := 0; i < size; i++ {
34 dst[i] = byte(i & 127)
35 }
36 for n := 0; n <= size; n++ {
37 for x := 0; x <= size-n; x++ {
38 for y := 0; y <= size-n; y++ {
39 copy(dst[y:y+n], src[x:x+n])
40 for i := 0; i < y; i++ {
41 if dst[i] != byte(i&127) {
42 t.Fatalf("prefix dst[%d] = %d", i, dst[i])
43 }
44 }
45 for i := y; i < y+n; i++ {
46 if dst[i] != byte(128+((i-y+x)&127)) {
47 t.Fatalf("copied dst[%d] = %d", i, dst[i])
48 }
49 dst[i] = byte(i & 127)
50 }
51 for i := y + n; i < size; i++ {
52 if dst[i] != byte(i&127) {
53 t.Fatalf("suffix dst[%d] = %d", i, dst[i])
54 }
55 }
56 }
57 }
58 }
59 }
60
61 func TestMemmoveAlias(t *testing.T) {
62 if *flagQuick {
63 t.Skip("-quick")
64 }
65 t.Parallel()
66 size := 256
67 if testing.Short() {
68 size = 128 + 16
69 }
70 buf := make([]byte, size)
71 for i := 0; i < size; i++ {
72 buf[i] = byte(i)
73 }
74 for n := 0; n <= size; n++ {
75 for x := 0; x <= size-n; x++ {
76 for y := 0; y <= size-n; y++ {
77 copy(buf[y:y+n], buf[x:x+n])
78 for i := 0; i < y; i++ {
79 if buf[i] != byte(i) {
80 t.Fatalf("prefix buf[%d] = %d", i, buf[i])
81 }
82 }
83 for i := y; i < y+n; i++ {
84 if buf[i] != byte(i-y+x) {
85 t.Fatalf("copied buf[%d] = %d", i, buf[i])
86 }
87 buf[i] = byte(i)
88 }
89 for i := y + n; i < size; i++ {
90 if buf[i] != byte(i) {
91 t.Fatalf("suffix buf[%d] = %d", i, buf[i])
92 }
93 }
94 }
95 }
96 }
97 }
98
99 func TestMemmoveLarge0x180000(t *testing.T) {
100 if testing.Short() && testenv.Builder() == "" {
101 t.Skip("-short")
102 }
103
104 t.Parallel()
105 if race.Enabled {
106 t.Skip("skipping large memmove test under race detector")
107 }
108 testSize(t, 0x180000)
109 }
110
111 func TestMemmoveOverlapLarge0x120000(t *testing.T) {
112 if testing.Short() && testenv.Builder() == "" {
113 t.Skip("-short")
114 }
115
116 t.Parallel()
117 if race.Enabled {
118 t.Skip("skipping large memmove test under race detector")
119 }
120 testOverlap(t, 0x120000)
121 }
122
123 func testSize(t *testing.T, size int) {
124 src := make([]byte, size)
125 dst := make([]byte, size)
126 _, _ = rand.Read(src)
127 _, _ = rand.Read(dst)
128
129 ref := make([]byte, size)
130 copyref(ref, dst)
131
132 for n := size - 50; n > 1; n >>= 1 {
133 for x := 0; x <= size-n; x = x*7 + 1 {
134 for y := 0; y <= size-n; y = y*9 + 1 {
135 copy(dst[y:y+n], src[x:x+n])
136 copyref(ref[y:y+n], src[x:x+n])
137 p := cmpb(dst, ref)
138 if p >= 0 {
139 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])
140 }
141 }
142 }
143 }
144 }
145
146 func testOverlap(t *testing.T, size int) {
147 src := make([]byte, size)
148 test := make([]byte, size)
149 ref := make([]byte, size)
150 _, _ = rand.Read(src)
151
152 for n := size - 50; n > 1; n >>= 1 {
153 for x := 0; x <= size-n; x = x*7 + 1 {
154 for y := 0; y <= size-n; y = y*9 + 1 {
155
156 copyref(test, src)
157 copyref(ref, src)
158 copy(test[y:y+n], test[x:x+n])
159 if y <= x {
160 copyref(ref[y:y+n], ref[x:x+n])
161 } else {
162 copybw(ref[y:y+n], ref[x:x+n])
163 }
164 p := cmpb(test, ref)
165 if p >= 0 {
166 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])
167 }
168 }
169 }
170 }
171
172 }
173
174
175 func copyref(dst, src []byte) {
176 for i, v := range src {
177 dst[i] = v
178 }
179 }
180
181
182 func copybw(dst, src []byte) {
183 if len(src) == 0 {
184 return
185 }
186 for i := len(src) - 1; i >= 0; i-- {
187 dst[i] = src[i]
188 }
189 }
190
191
192 func matchLen(a, b []byte, max int) int {
193 a = a[:max]
194 b = b[:max]
195 for i, av := range a {
196 if b[i] != av {
197 return i
198 }
199 }
200 return max
201 }
202
203 func cmpb(a, b []byte) int {
204 l := matchLen(a, b, len(a))
205 if l == len(a) {
206 return -1
207 }
208 return l
209 }
210
211
212
213 func TestMemmoveAtomicity(t *testing.T) {
214 if race.Enabled {
215 t.Skip("skip under the race detector -- this test is intentionally racy")
216 }
217
218 var x int
219
220 for _, backward := range []bool{true, false} {
221 for _, n := range []int{3, 4, 5, 6, 7, 8, 9, 10, 15, 25, 49} {
222 n := n
223
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 BenchmarkClearFat7(b *testing.B) {
522 p := new([7]byte)
523 Escape(p)
524 b.ResetTimer()
525 for i := 0; i < b.N; i++ {
526 *p = [7]byte{}
527 }
528 }
529
530 func BenchmarkClearFat8(b *testing.B) {
531 p := new([8 / 4]uint32)
532 Escape(p)
533 b.ResetTimer()
534 for i := 0; i < b.N; i++ {
535 *p = [8 / 4]uint32{}
536 }
537 }
538
539 func BenchmarkClearFat11(b *testing.B) {
540 p := new([11]byte)
541 Escape(p)
542 b.ResetTimer()
543 for i := 0; i < b.N; i++ {
544 *p = [11]byte{}
545 }
546 }
547
548 func BenchmarkClearFat12(b *testing.B) {
549 p := new([12 / 4]uint32)
550 Escape(p)
551 b.ResetTimer()
552 for i := 0; i < b.N; i++ {
553 *p = [12 / 4]uint32{}
554 }
555 }
556
557 func BenchmarkClearFat13(b *testing.B) {
558 p := new([13]byte)
559 Escape(p)
560 b.ResetTimer()
561 for i := 0; i < b.N; i++ {
562 *p = [13]byte{}
563 }
564 }
565
566 func BenchmarkClearFat14(b *testing.B) {
567 p := new([14]byte)
568 Escape(p)
569 b.ResetTimer()
570 for i := 0; i < b.N; i++ {
571 *p = [14]byte{}
572 }
573 }
574
575 func BenchmarkClearFat15(b *testing.B) {
576 p := new([15]byte)
577 Escape(p)
578 b.ResetTimer()
579 for i := 0; i < b.N; i++ {
580 *p = [15]byte{}
581 }
582 }
583
584 func BenchmarkClearFat16(b *testing.B) {
585 p := new([16 / 4]uint32)
586 Escape(p)
587 b.ResetTimer()
588 for i := 0; i < b.N; i++ {
589 *p = [16 / 4]uint32{}
590 }
591 }
592
593 func BenchmarkClearFat24(b *testing.B) {
594 p := new([24 / 4]uint32)
595 Escape(p)
596 b.ResetTimer()
597 for i := 0; i < b.N; i++ {
598 *p = [24 / 4]uint32{}
599 }
600 }
601
602 func BenchmarkClearFat32(b *testing.B) {
603 p := new([32 / 4]uint32)
604 Escape(p)
605 b.ResetTimer()
606 for i := 0; i < b.N; i++ {
607 *p = [32 / 4]uint32{}
608 }
609 }
610
611 func BenchmarkClearFat40(b *testing.B) {
612 p := new([40 / 4]uint32)
613 Escape(p)
614 b.ResetTimer()
615 for i := 0; i < b.N; i++ {
616 *p = [40 / 4]uint32{}
617 }
618 }
619
620 func BenchmarkClearFat48(b *testing.B) {
621 p := new([48 / 4]uint32)
622 Escape(p)
623 b.ResetTimer()
624 for i := 0; i < b.N; i++ {
625 *p = [48 / 4]uint32{}
626 }
627 }
628
629 func BenchmarkClearFat56(b *testing.B) {
630 p := new([56 / 4]uint32)
631 Escape(p)
632 b.ResetTimer()
633 for i := 0; i < b.N; i++ {
634 *p = [56 / 4]uint32{}
635 }
636 }
637
638 func BenchmarkClearFat64(b *testing.B) {
639 p := new([64 / 4]uint32)
640 Escape(p)
641 b.ResetTimer()
642 for i := 0; i < b.N; i++ {
643 *p = [64 / 4]uint32{}
644 }
645 }
646
647 func BenchmarkClearFat72(b *testing.B) {
648 p := new([72 / 4]uint32)
649 Escape(p)
650 b.ResetTimer()
651 for i := 0; i < b.N; i++ {
652 *p = [72 / 4]uint32{}
653 }
654 }
655
656 func BenchmarkClearFat128(b *testing.B) {
657 p := new([128 / 4]uint32)
658 Escape(p)
659 b.ResetTimer()
660 for i := 0; i < b.N; i++ {
661 *p = [128 / 4]uint32{}
662 }
663 }
664
665 func BenchmarkClearFat256(b *testing.B) {
666 p := new([256 / 4]uint32)
667 Escape(p)
668 b.ResetTimer()
669 for i := 0; i < b.N; i++ {
670 *p = [256 / 4]uint32{}
671 }
672 }
673
674 func BenchmarkClearFat512(b *testing.B) {
675 p := new([512 / 4]uint32)
676 Escape(p)
677 b.ResetTimer()
678 for i := 0; i < b.N; i++ {
679 *p = [512 / 4]uint32{}
680 }
681 }
682
683 func BenchmarkClearFat1024(b *testing.B) {
684 p := new([1024 / 4]uint32)
685 Escape(p)
686 b.ResetTimer()
687 for i := 0; i < b.N; i++ {
688 *p = [1024 / 4]uint32{}
689 }
690 }
691
692 func BenchmarkClearFat1032(b *testing.B) {
693 p := new([1032 / 4]uint32)
694 Escape(p)
695 b.ResetTimer()
696 for i := 0; i < b.N; i++ {
697 *p = [1032 / 4]uint32{}
698 }
699 }
700
701 func BenchmarkClearFat1040(b *testing.B) {
702 p := new([1040 / 4]uint32)
703 Escape(p)
704 b.ResetTimer()
705 for i := 0; i < b.N; i++ {
706 *p = [1040 / 4]uint32{}
707 }
708 }
709
710 func BenchmarkCopyFat7(b *testing.B) {
711 var x [7]byte
712 p := new([7]byte)
713 Escape(p)
714 b.ResetTimer()
715 for i := 0; i < b.N; i++ {
716 *p = x
717 }
718 }
719
720 func BenchmarkCopyFat8(b *testing.B) {
721 var x [8 / 4]uint32
722 p := new([8 / 4]uint32)
723 Escape(p)
724 b.ResetTimer()
725 for i := 0; i < b.N; i++ {
726 *p = x
727 }
728 }
729
730 func BenchmarkCopyFat11(b *testing.B) {
731 var x [11]byte
732 p := new([11]byte)
733 Escape(p)
734 b.ResetTimer()
735 for i := 0; i < b.N; i++ {
736 *p = x
737 }
738 }
739
740 func BenchmarkCopyFat12(b *testing.B) {
741 var x [12 / 4]uint32
742 p := new([12 / 4]uint32)
743 Escape(p)
744 b.ResetTimer()
745 for i := 0; i < b.N; i++ {
746 *p = x
747 }
748 }
749
750 func BenchmarkCopyFat13(b *testing.B) {
751 var x [13]byte
752 p := new([13]byte)
753 Escape(p)
754 b.ResetTimer()
755 for i := 0; i < b.N; i++ {
756 *p = x
757 }
758 }
759
760 func BenchmarkCopyFat14(b *testing.B) {
761 var x [14]byte
762 p := new([14]byte)
763 Escape(p)
764 b.ResetTimer()
765 for i := 0; i < b.N; i++ {
766 *p = x
767 }
768 }
769
770 func BenchmarkCopyFat15(b *testing.B) {
771 var x [15]byte
772 p := new([15]byte)
773 Escape(p)
774 b.ResetTimer()
775 for i := 0; i < b.N; i++ {
776 *p = x
777 }
778 }
779
780 func BenchmarkCopyFat16(b *testing.B) {
781 var x [16 / 4]uint32
782 p := new([16 / 4]uint32)
783 Escape(p)
784 b.ResetTimer()
785 for i := 0; i < b.N; i++ {
786 *p = x
787 }
788 }
789
790 func BenchmarkCopyFat24(b *testing.B) {
791 var x [24 / 4]uint32
792 p := new([24 / 4]uint32)
793 Escape(p)
794 b.ResetTimer()
795 for i := 0; i < b.N; i++ {
796 *p = x
797 }
798 }
799
800 func BenchmarkCopyFat32(b *testing.B) {
801 var x [32 / 4]uint32
802 p := new([32 / 4]uint32)
803 Escape(p)
804 b.ResetTimer()
805 for i := 0; i < b.N; i++ {
806 *p = x
807 }
808 }
809
810 func BenchmarkCopyFat64(b *testing.B) {
811 var x [64 / 4]uint32
812 p := new([64 / 4]uint32)
813 Escape(p)
814 b.ResetTimer()
815 for i := 0; i < b.N; i++ {
816 *p = x
817 }
818 }
819
820 func BenchmarkCopyFat72(b *testing.B) {
821 var x [72 / 4]uint32
822 p := new([72 / 4]uint32)
823 Escape(p)
824 b.ResetTimer()
825 for i := 0; i < b.N; i++ {
826 *p = x
827 }
828 }
829
830 func BenchmarkCopyFat128(b *testing.B) {
831 var x [128 / 4]uint32
832 p := new([128 / 4]uint32)
833 Escape(p)
834 b.ResetTimer()
835 for i := 0; i < b.N; i++ {
836 *p = x
837 }
838 }
839
840 func BenchmarkCopyFat256(b *testing.B) {
841 var x [256 / 4]uint32
842 p := new([256 / 4]uint32)
843 Escape(p)
844 b.ResetTimer()
845 for i := 0; i < b.N; i++ {
846 *p = x
847 }
848 }
849
850 func BenchmarkCopyFat512(b *testing.B) {
851 var x [512 / 4]uint32
852 p := new([512 / 4]uint32)
853 Escape(p)
854 b.ResetTimer()
855 for i := 0; i < b.N; i++ {
856 *p = x
857 }
858 }
859
860 func BenchmarkCopyFat520(b *testing.B) {
861 var x [520 / 4]uint32
862 p := new([520 / 4]uint32)
863 Escape(p)
864 b.ResetTimer()
865 for i := 0; i < b.N; i++ {
866 *p = x
867 }
868 }
869
870 func BenchmarkCopyFat1024(b *testing.B) {
871 var x [1024 / 4]uint32
872 p := new([1024 / 4]uint32)
873 Escape(p)
874 b.ResetTimer()
875 for i := 0; i < b.N; i++ {
876 *p = x
877 }
878 }
879
880 func BenchmarkCopyFat1032(b *testing.B) {
881 var x [1032 / 4]uint32
882 p := new([1032 / 4]uint32)
883 Escape(p)
884 b.ResetTimer()
885 for i := 0; i < b.N; i++ {
886 *p = x
887 }
888 }
889
890 func BenchmarkCopyFat1040(b *testing.B) {
891 var x [1040 / 4]uint32
892 p := new([1040 / 4]uint32)
893 Escape(p)
894 b.ResetTimer()
895 for i := 0; i < b.N; i++ {
896 *p = x
897 }
898 }
899
900
901
902
903 func BenchmarkIssue18740(b *testing.B) {
904 benchmarks := []struct {
905 name string
906 nbyte int
907 f func([]byte) uint64
908 }{
909 {"2byte", 2, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint16(buf)) }},
910 {"4byte", 4, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint32(buf)) }},
911 {"8byte", 8, func(buf []byte) uint64 { return binary.LittleEndian.Uint64(buf) }},
912 }
913
914 var g [4096]byte
915 for _, bm := range benchmarks {
916 buf := make([]byte, bm.nbyte)
917 b.Run(bm.name, func(b *testing.B) {
918 for j := 0; j < b.N; j++ {
919 for i := 0; i < 4096; i += bm.nbyte {
920 copy(buf[:], g[i:])
921 sink += bm.f(buf[:])
922 }
923 }
924 })
925 }
926 }
927
928 var memclrSink []int8
929
930 func BenchmarkMemclrKnownSize1(b *testing.B) {
931 var x [1]int8
932
933 b.SetBytes(1)
934 for i := 0; i < b.N; i++ {
935 for a := range x {
936 x[a] = 0
937 }
938 }
939
940 memclrSink = x[:]
941 }
942 func BenchmarkMemclrKnownSize2(b *testing.B) {
943 var x [2]int8
944
945 b.SetBytes(2)
946 for i := 0; i < b.N; i++ {
947 for a := range x {
948 x[a] = 0
949 }
950 }
951
952 memclrSink = x[:]
953 }
954 func BenchmarkMemclrKnownSize4(b *testing.B) {
955 var x [4]int8
956
957 b.SetBytes(4)
958 for i := 0; i < b.N; i++ {
959 for a := range x {
960 x[a] = 0
961 }
962 }
963
964 memclrSink = x[:]
965 }
966 func BenchmarkMemclrKnownSize8(b *testing.B) {
967 var x [8]int8
968
969 b.SetBytes(8)
970 for i := 0; i < b.N; i++ {
971 for a := range x {
972 x[a] = 0
973 }
974 }
975
976 memclrSink = x[:]
977 }
978 func BenchmarkMemclrKnownSize16(b *testing.B) {
979 var x [16]int8
980
981 b.SetBytes(16)
982 for i := 0; i < b.N; i++ {
983 for a := range x {
984 x[a] = 0
985 }
986 }
987
988 memclrSink = x[:]
989 }
990 func BenchmarkMemclrKnownSize32(b *testing.B) {
991 var x [32]int8
992
993 b.SetBytes(32)
994 for i := 0; i < b.N; i++ {
995 for a := range x {
996 x[a] = 0
997 }
998 }
999
1000 memclrSink = x[:]
1001 }
1002 func BenchmarkMemclrKnownSize64(b *testing.B) {
1003 var x [64]int8
1004
1005 b.SetBytes(64)
1006 for i := 0; i < b.N; i++ {
1007 for a := range x {
1008 x[a] = 0
1009 }
1010 }
1011
1012 memclrSink = x[:]
1013 }
1014 func BenchmarkMemclrKnownSize112(b *testing.B) {
1015 var x [112]int8
1016
1017 b.SetBytes(112)
1018 for i := 0; i < b.N; i++ {
1019 for a := range x {
1020 x[a] = 0
1021 }
1022 }
1023
1024 memclrSink = x[:]
1025 }
1026
1027 func BenchmarkMemclrKnownSize128(b *testing.B) {
1028 var x [128]int8
1029
1030 b.SetBytes(128)
1031 for i := 0; i < b.N; i++ {
1032 for a := range x {
1033 x[a] = 0
1034 }
1035 }
1036
1037 memclrSink = x[:]
1038 }
1039
1040 func BenchmarkMemclrKnownSize192(b *testing.B) {
1041 var x [192]int8
1042
1043 b.SetBytes(192)
1044 for i := 0; i < b.N; i++ {
1045 for a := range x {
1046 x[a] = 0
1047 }
1048 }
1049
1050 memclrSink = x[:]
1051 }
1052
1053 func BenchmarkMemclrKnownSize248(b *testing.B) {
1054 var x [248]int8
1055
1056 b.SetBytes(248)
1057 for i := 0; i < b.N; i++ {
1058 for a := range x {
1059 x[a] = 0
1060 }
1061 }
1062
1063 memclrSink = x[:]
1064 }
1065
1066 func BenchmarkMemclrKnownSize256(b *testing.B) {
1067 var x [256]int8
1068
1069 b.SetBytes(256)
1070 for i := 0; i < b.N; i++ {
1071 for a := range x {
1072 x[a] = 0
1073 }
1074 }
1075
1076 memclrSink = x[:]
1077 }
1078 func BenchmarkMemclrKnownSize512(b *testing.B) {
1079 var x [512]int8
1080
1081 b.SetBytes(512)
1082 for i := 0; i < b.N; i++ {
1083 for a := range x {
1084 x[a] = 0
1085 }
1086 }
1087
1088 memclrSink = x[:]
1089 }
1090 func BenchmarkMemclrKnownSize1024(b *testing.B) {
1091 var x [1024]int8
1092
1093 b.SetBytes(1024)
1094 for i := 0; i < b.N; i++ {
1095 for a := range x {
1096 x[a] = 0
1097 }
1098 }
1099
1100 memclrSink = x[:]
1101 }
1102 func BenchmarkMemclrKnownSize4096(b *testing.B) {
1103 var x [4096]int8
1104
1105 b.SetBytes(4096)
1106 for i := 0; i < b.N; i++ {
1107 for a := range x {
1108 x[a] = 0
1109 }
1110 }
1111
1112 memclrSink = x[:]
1113 }
1114 func BenchmarkMemclrKnownSize512KiB(b *testing.B) {
1115 var x [524288]int8
1116
1117 b.SetBytes(524288)
1118 for i := 0; i < b.N; i++ {
1119 for a := range x {
1120 x[a] = 0
1121 }
1122 }
1123
1124 memclrSink = x[:]
1125 }
1126
View as plain text