]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/memmove_test.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / runtime / memmove_test.go
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
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++ { // offset in src
38                         for y := 0; y <= size-n; y++ { // offset in dst
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) // reset dst
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++ { // src offset
76                         for y := 0; y <= size-n; y++ { // dst offset
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) // reset buf
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 { // offset in src
134                         for y := 0; y <= size-n; y = y*9 + 1 { // offset in dst
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 { // offset in src
154                         for y := 0; y <= size-n; y = y*9 + 1 { // offset in dst
155                                 // Reset input
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 // Forward copy.
175 func copyref(dst, src []byte) {
176         for i, v := range src {
177                 dst[i] = v
178         }
179 }
180
181 // Backwards copy
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 // Returns offset of difference
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 // Ensure that memmove writes pointers atomically, so the GC won't
212 // observe a partially updated pointer.
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                         // test copying [N]*int.
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                                 // Use overlapping src and dst to force forward/backward copy.
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                                 for i := range dst {
244                                         dst[i] = nil
245                                 }
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                 for i := 0; i < b.N; i++ {
298                         copy(x, y)
299                 }
300         })
301 }
302
303 func BenchmarkMemmoveOverlap(b *testing.B) {
304         benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
305                 x := make([]byte, n+16)
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                 for i := 0; i < b.N; i++ {
317                         copy(x[1:], y)
318                 }
319         })
320 }
321
322 func BenchmarkMemmoveUnalignedDstOverlap(b *testing.B) {
323         benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
324                 x := make([]byte, n+16)
325                 for i := 0; i < b.N; i++ {
326                         copy(x[16:n+16], x[1:n+1])
327                 }
328         })
329 }
330
331 func BenchmarkMemmoveUnalignedSrc(b *testing.B) {
332         benchmarkSizes(b, bufSizes, func(b *testing.B, n int) {
333                 x := make([]byte, n)
334                 y := make([]byte, n+1)
335                 for i := 0; i < b.N; i++ {
336                         copy(x, y[1:])
337                 }
338         })
339 }
340
341 func BenchmarkMemmoveUnalignedSrcDst(b *testing.B) {
342         for _, n := range []int{16, 64, 256, 4096, 65536} {
343                 buf := make([]byte, (n+8)*2)
344                 x := buf[:len(buf)/2]
345                 y := buf[len(buf)/2:]
346                 for _, off := range []int{0, 1, 4, 7} {
347                         b.Run(fmt.Sprint("f_", n, off), func(b *testing.B) {
348                                 b.SetBytes(int64(n))
349                                 for i := 0; i < b.N; i++ {
350                                         copy(x[off:n+off], y[off:n+off])
351                                 }
352                         })
353
354                         b.Run(fmt.Sprint("b_", n, off), func(b *testing.B) {
355                                 b.SetBytes(int64(n))
356                                 for i := 0; i < b.N; i++ {
357                                         copy(y[off:n+off], x[off:n+off])
358                                 }
359                         })
360                 }
361         }
362 }
363
364 func BenchmarkMemmoveUnalignedSrcOverlap(b *testing.B) {
365         benchmarkSizes(b, bufSizesOverlap, func(b *testing.B, n int) {
366                 x := make([]byte, n+1)
367                 for i := 0; i < b.N; i++ {
368                         copy(x[1:n+1], x[:n])
369                 }
370         })
371 }
372
373 func TestMemclr(t *testing.T) {
374         size := 512
375         if testing.Short() {
376                 size = 128 + 16
377         }
378         mem := make([]byte, size)
379         for i := 0; i < size; i++ {
380                 mem[i] = 0xee
381         }
382         for n := 0; n < size; n++ {
383                 for x := 0; x <= size-n; x++ { // offset in mem
384                         MemclrBytes(mem[x : x+n])
385                         for i := 0; i < x; i++ {
386                                 if mem[i] != 0xee {
387                                         t.Fatalf("overwrite prefix mem[%d] = %d", i, mem[i])
388                                 }
389                         }
390                         for i := x; i < x+n; i++ {
391                                 if mem[i] != 0 {
392                                         t.Fatalf("failed clear mem[%d] = %d", i, mem[i])
393                                 }
394                                 mem[i] = 0xee
395                         }
396                         for i := x + n; i < size; i++ {
397                                 if mem[i] != 0xee {
398                                         t.Fatalf("overwrite suffix mem[%d] = %d", i, mem[i])
399                                 }
400                         }
401                 }
402         }
403 }
404
405 func BenchmarkMemclr(b *testing.B) {
406         for _, n := range []int{5, 16, 64, 256, 4096, 65536} {
407                 x := make([]byte, n)
408                 b.Run(fmt.Sprint(n), func(b *testing.B) {
409                         b.SetBytes(int64(n))
410                         for i := 0; i < b.N; i++ {
411                                 MemclrBytes(x)
412                         }
413                 })
414         }
415         for _, m := range []int{1, 4, 8, 16, 64} {
416                 x := make([]byte, m<<20)
417                 b.Run(fmt.Sprint(m, "M"), func(b *testing.B) {
418                         b.SetBytes(int64(m << 20))
419                         for i := 0; i < b.N; i++ {
420                                 MemclrBytes(x)
421                         }
422                 })
423         }
424 }
425
426 func BenchmarkMemclrUnaligned(b *testing.B) {
427         for _, off := range []int{0, 1, 4, 7} {
428                 for _, n := range []int{5, 16, 64, 256, 4096, 65536} {
429                         x := make([]byte, n+off)
430                         b.Run(fmt.Sprint(off, n), func(b *testing.B) {
431                                 b.SetBytes(int64(n))
432                                 for i := 0; i < b.N; i++ {
433                                         MemclrBytes(x[off:])
434                                 }
435                         })
436                 }
437         }
438
439         for _, off := range []int{0, 1, 4, 7} {
440                 for _, m := range []int{1, 4, 8, 16, 64} {
441                         x := make([]byte, (m<<20)+off)
442                         b.Run(fmt.Sprint(off, m, "M"), func(b *testing.B) {
443                                 b.SetBytes(int64(m << 20))
444                                 for i := 0; i < b.N; i++ {
445                                         MemclrBytes(x[off:])
446                                 }
447                         })
448                 }
449         }
450 }
451
452 func BenchmarkGoMemclr(b *testing.B) {
453         benchmarkSizes(b, []int{5, 16, 64, 256}, func(b *testing.B, n int) {
454                 x := make([]byte, n)
455                 for i := 0; i < b.N; i++ {
456                         for j := range x {
457                                 x[j] = 0
458                         }
459                 }
460         })
461 }
462
463 func BenchmarkMemclrRange(b *testing.B) {
464         type RunData struct {
465                 data []int
466         }
467
468         benchSizes := []RunData{
469                 {[]int{1043, 1078, 1894, 1582, 1044, 1165, 1467, 1100, 1919, 1562, 1932, 1645,
470                         1412, 1038, 1576, 1200, 1029, 1336, 1095, 1494, 1350, 1025, 1502, 1548, 1316, 1296,
471                         1868, 1639, 1546, 1626, 1642, 1308, 1726, 1665, 1678, 1187, 1515, 1598, 1353, 1237,
472                         1977, 1452, 2012, 1914, 1514, 1136, 1975, 1618, 1536, 1695, 1600, 1733, 1392, 1099,
473                         1358, 1996, 1224, 1783, 1197, 1838, 1460, 1556, 1554, 2020}}, // 1kb-2kb
474                 {[]int{3964, 5139, 6573, 7775, 6553, 2413, 3466, 5394, 2469, 7336, 7091, 6745,
475                         4028, 5643, 6164, 3475, 4138, 6908, 7559, 3335, 5660, 4122, 3945, 2082, 7564, 6584,
476                         5111, 2288, 6789, 2797, 4928, 7986, 5163, 5447, 2999, 4968, 3174, 3202, 7908, 8137,
477                         4735, 6161, 4646, 7592, 3083, 5329, 3687, 2754, 3599, 7231, 6455, 2549, 8063, 2189,
478                         7121, 5048, 4277, 6626, 6306, 2815, 7473, 3963, 7549, 7255}}, // 2kb-8kb
479                 {[]int{16304, 15936, 15760, 4736, 9136, 11184, 10160, 5952, 14560, 15744,
480                         6624, 5872, 13088, 14656, 14192, 10304, 4112, 10384, 9344, 4496, 11392, 7024,
481                         5200, 10064, 14784, 5808, 13504, 10480, 8512, 4896, 13264, 5600}}, // 4kb-16kb
482                 {[]int{164576, 233136, 220224, 183280, 214112, 217248, 228560, 201728}}, // 128kb-256kb
483         }
484
485         for _, t := range benchSizes {
486                 total := 0
487                 minLen := 0
488                 maxLen := 0
489
490                 for _, clrLen := range t.data {
491                         maxLen = max(maxLen, clrLen)
492                         if clrLen < minLen || minLen == 0 {
493                                 minLen = clrLen
494                         }
495                         total += clrLen
496                 }
497                 buffer := make([]byte, maxLen)
498
499                 text := ""
500                 if minLen >= (1 << 20) {
501                         text = fmt.Sprint(minLen>>20, "M ", (maxLen+(1<<20-1))>>20, "M")
502                 } else if minLen >= (1 << 10) {
503                         text = fmt.Sprint(minLen>>10, "K ", (maxLen+(1<<10-1))>>10, "K")
504                 } else {
505                         text = fmt.Sprint(minLen, " ", maxLen)
506                 }
507                 b.Run(text, func(b *testing.B) {
508                         b.SetBytes(int64(total))
509                         for i := 0; i < b.N; i++ {
510                                 for _, clrLen := range t.data {
511                                         MemclrBytes(buffer[:clrLen])
512                                 }
513                         }
514                 })
515         }
516 }
517
518 func BenchmarkClearFat7(b *testing.B) {
519         p := new([7]byte)
520         Escape(p)
521         b.ResetTimer()
522         for i := 0; i < b.N; i++ {
523                 *p = [7]byte{}
524         }
525 }
526
527 func BenchmarkClearFat8(b *testing.B) {
528         p := new([8 / 4]uint32)
529         Escape(p)
530         b.ResetTimer()
531         for i := 0; i < b.N; i++ {
532                 *p = [8 / 4]uint32{}
533         }
534 }
535
536 func BenchmarkClearFat11(b *testing.B) {
537         p := new([11]byte)
538         Escape(p)
539         b.ResetTimer()
540         for i := 0; i < b.N; i++ {
541                 *p = [11]byte{}
542         }
543 }
544
545 func BenchmarkClearFat12(b *testing.B) {
546         p := new([12 / 4]uint32)
547         Escape(p)
548         b.ResetTimer()
549         for i := 0; i < b.N; i++ {
550                 *p = [12 / 4]uint32{}
551         }
552 }
553
554 func BenchmarkClearFat13(b *testing.B) {
555         p := new([13]byte)
556         Escape(p)
557         b.ResetTimer()
558         for i := 0; i < b.N; i++ {
559                 *p = [13]byte{}
560         }
561 }
562
563 func BenchmarkClearFat14(b *testing.B) {
564         p := new([14]byte)
565         Escape(p)
566         b.ResetTimer()
567         for i := 0; i < b.N; i++ {
568                 *p = [14]byte{}
569         }
570 }
571
572 func BenchmarkClearFat15(b *testing.B) {
573         p := new([15]byte)
574         Escape(p)
575         b.ResetTimer()
576         for i := 0; i < b.N; i++ {
577                 *p = [15]byte{}
578         }
579 }
580
581 func BenchmarkClearFat16(b *testing.B) {
582         p := new([16 / 4]uint32)
583         Escape(p)
584         b.ResetTimer()
585         for i := 0; i < b.N; i++ {
586                 *p = [16 / 4]uint32{}
587         }
588 }
589
590 func BenchmarkClearFat24(b *testing.B) {
591         p := new([24 / 4]uint32)
592         Escape(p)
593         b.ResetTimer()
594         for i := 0; i < b.N; i++ {
595                 *p = [24 / 4]uint32{}
596         }
597 }
598
599 func BenchmarkClearFat32(b *testing.B) {
600         p := new([32 / 4]uint32)
601         Escape(p)
602         b.ResetTimer()
603         for i := 0; i < b.N; i++ {
604                 *p = [32 / 4]uint32{}
605         }
606 }
607
608 func BenchmarkClearFat40(b *testing.B) {
609         p := new([40 / 4]uint32)
610         Escape(p)
611         b.ResetTimer()
612         for i := 0; i < b.N; i++ {
613                 *p = [40 / 4]uint32{}
614         }
615 }
616
617 func BenchmarkClearFat48(b *testing.B) {
618         p := new([48 / 4]uint32)
619         Escape(p)
620         b.ResetTimer()
621         for i := 0; i < b.N; i++ {
622                 *p = [48 / 4]uint32{}
623         }
624 }
625
626 func BenchmarkClearFat56(b *testing.B) {
627         p := new([56 / 4]uint32)
628         Escape(p)
629         b.ResetTimer()
630         for i := 0; i < b.N; i++ {
631                 *p = [56 / 4]uint32{}
632         }
633 }
634
635 func BenchmarkClearFat64(b *testing.B) {
636         p := new([64 / 4]uint32)
637         Escape(p)
638         b.ResetTimer()
639         for i := 0; i < b.N; i++ {
640                 *p = [64 / 4]uint32{}
641         }
642 }
643
644 func BenchmarkClearFat72(b *testing.B) {
645         p := new([72 / 4]uint32)
646         Escape(p)
647         b.ResetTimer()
648         for i := 0; i < b.N; i++ {
649                 *p = [72 / 4]uint32{}
650         }
651 }
652
653 func BenchmarkClearFat128(b *testing.B) {
654         p := new([128 / 4]uint32)
655         Escape(p)
656         b.ResetTimer()
657         for i := 0; i < b.N; i++ {
658                 *p = [128 / 4]uint32{}
659         }
660 }
661
662 func BenchmarkClearFat256(b *testing.B) {
663         p := new([256 / 4]uint32)
664         Escape(p)
665         b.ResetTimer()
666         for i := 0; i < b.N; i++ {
667                 *p = [256 / 4]uint32{}
668         }
669 }
670
671 func BenchmarkClearFat512(b *testing.B) {
672         p := new([512 / 4]uint32)
673         Escape(p)
674         b.ResetTimer()
675         for i := 0; i < b.N; i++ {
676                 *p = [512 / 4]uint32{}
677         }
678 }
679
680 func BenchmarkClearFat1024(b *testing.B) {
681         p := new([1024 / 4]uint32)
682         Escape(p)
683         b.ResetTimer()
684         for i := 0; i < b.N; i++ {
685                 *p = [1024 / 4]uint32{}
686         }
687 }
688
689 func BenchmarkClearFat1032(b *testing.B) {
690         p := new([1032 / 4]uint32)
691         Escape(p)
692         b.ResetTimer()
693         for i := 0; i < b.N; i++ {
694                 *p = [1032 / 4]uint32{}
695         }
696 }
697
698 func BenchmarkClearFat1040(b *testing.B) {
699         p := new([1040 / 4]uint32)
700         Escape(p)
701         b.ResetTimer()
702         for i := 0; i < b.N; i++ {
703                 *p = [1040 / 4]uint32{}
704         }
705 }
706
707 func BenchmarkCopyFat7(b *testing.B) {
708         var x [7]byte
709         p := new([7]byte)
710         Escape(p)
711         b.ResetTimer()
712         for i := 0; i < b.N; i++ {
713                 *p = x
714         }
715 }
716
717 func BenchmarkCopyFat8(b *testing.B) {
718         var x [8 / 4]uint32
719         p := new([8 / 4]uint32)
720         Escape(p)
721         b.ResetTimer()
722         for i := 0; i < b.N; i++ {
723                 *p = x
724         }
725 }
726
727 func BenchmarkCopyFat11(b *testing.B) {
728         var x [11]byte
729         p := new([11]byte)
730         Escape(p)
731         b.ResetTimer()
732         for i := 0; i < b.N; i++ {
733                 *p = x
734         }
735 }
736
737 func BenchmarkCopyFat12(b *testing.B) {
738         var x [12 / 4]uint32
739         p := new([12 / 4]uint32)
740         Escape(p)
741         b.ResetTimer()
742         for i := 0; i < b.N; i++ {
743                 *p = x
744         }
745 }
746
747 func BenchmarkCopyFat13(b *testing.B) {
748         var x [13]byte
749         p := new([13]byte)
750         Escape(p)
751         b.ResetTimer()
752         for i := 0; i < b.N; i++ {
753                 *p = x
754         }
755 }
756
757 func BenchmarkCopyFat14(b *testing.B) {
758         var x [14]byte
759         p := new([14]byte)
760         Escape(p)
761         b.ResetTimer()
762         for i := 0; i < b.N; i++ {
763                 *p = x
764         }
765 }
766
767 func BenchmarkCopyFat15(b *testing.B) {
768         var x [15]byte
769         p := new([15]byte)
770         Escape(p)
771         b.ResetTimer()
772         for i := 0; i < b.N; i++ {
773                 *p = x
774         }
775 }
776
777 func BenchmarkCopyFat16(b *testing.B) {
778         var x [16 / 4]uint32
779         p := new([16 / 4]uint32)
780         Escape(p)
781         b.ResetTimer()
782         for i := 0; i < b.N; i++ {
783                 *p = x
784         }
785 }
786
787 func BenchmarkCopyFat24(b *testing.B) {
788         var x [24 / 4]uint32
789         p := new([24 / 4]uint32)
790         Escape(p)
791         b.ResetTimer()
792         for i := 0; i < b.N; i++ {
793                 *p = x
794         }
795 }
796
797 func BenchmarkCopyFat32(b *testing.B) {
798         var x [32 / 4]uint32
799         p := new([32 / 4]uint32)
800         Escape(p)
801         b.ResetTimer()
802         for i := 0; i < b.N; i++ {
803                 *p = x
804         }
805 }
806
807 func BenchmarkCopyFat64(b *testing.B) {
808         var x [64 / 4]uint32
809         p := new([64 / 4]uint32)
810         Escape(p)
811         b.ResetTimer()
812         for i := 0; i < b.N; i++ {
813                 *p = x
814         }
815 }
816
817 func BenchmarkCopyFat72(b *testing.B) {
818         var x [72 / 4]uint32
819         p := new([72 / 4]uint32)
820         Escape(p)
821         b.ResetTimer()
822         for i := 0; i < b.N; i++ {
823                 *p = x
824         }
825 }
826
827 func BenchmarkCopyFat128(b *testing.B) {
828         var x [128 / 4]uint32
829         p := new([128 / 4]uint32)
830         Escape(p)
831         b.ResetTimer()
832         for i := 0; i < b.N; i++ {
833                 *p = x
834         }
835 }
836
837 func BenchmarkCopyFat256(b *testing.B) {
838         var x [256 / 4]uint32
839         p := new([256 / 4]uint32)
840         Escape(p)
841         b.ResetTimer()
842         for i := 0; i < b.N; i++ {
843                 *p = x
844         }
845 }
846
847 func BenchmarkCopyFat512(b *testing.B) {
848         var x [512 / 4]uint32
849         p := new([512 / 4]uint32)
850         Escape(p)
851         b.ResetTimer()
852         for i := 0; i < b.N; i++ {
853                 *p = x
854         }
855 }
856
857 func BenchmarkCopyFat520(b *testing.B) {
858         var x [520 / 4]uint32
859         p := new([520 / 4]uint32)
860         Escape(p)
861         b.ResetTimer()
862         for i := 0; i < b.N; i++ {
863                 *p = x
864         }
865 }
866
867 func BenchmarkCopyFat1024(b *testing.B) {
868         var x [1024 / 4]uint32
869         p := new([1024 / 4]uint32)
870         Escape(p)
871         b.ResetTimer()
872         for i := 0; i < b.N; i++ {
873                 *p = x
874         }
875 }
876
877 func BenchmarkCopyFat1032(b *testing.B) {
878         var x [1032 / 4]uint32
879         p := new([1032 / 4]uint32)
880         Escape(p)
881         b.ResetTimer()
882         for i := 0; i < b.N; i++ {
883                 *p = x
884         }
885 }
886
887 func BenchmarkCopyFat1040(b *testing.B) {
888         var x [1040 / 4]uint32
889         p := new([1040 / 4]uint32)
890         Escape(p)
891         b.ResetTimer()
892         for i := 0; i < b.N; i++ {
893                 *p = x
894         }
895 }
896
897 // BenchmarkIssue18740 ensures that memmove uses 4 and 8 byte load/store to move 4 and 8 bytes.
898 // It used to do 2 2-byte load/stores, which leads to a pipeline stall
899 // when we try to read the result with one 4-byte load.
900 func BenchmarkIssue18740(b *testing.B) {
901         benchmarks := []struct {
902                 name  string
903                 nbyte int
904                 f     func([]byte) uint64
905         }{
906                 {"2byte", 2, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint16(buf)) }},
907                 {"4byte", 4, func(buf []byte) uint64 { return uint64(binary.LittleEndian.Uint32(buf)) }},
908                 {"8byte", 8, func(buf []byte) uint64 { return binary.LittleEndian.Uint64(buf) }},
909         }
910
911         var g [4096]byte
912         for _, bm := range benchmarks {
913                 buf := make([]byte, bm.nbyte)
914                 b.Run(bm.name, func(b *testing.B) {
915                         for j := 0; j < b.N; j++ {
916                                 for i := 0; i < 4096; i += bm.nbyte {
917                                         copy(buf[:], g[i:])
918                                         sink += bm.f(buf[:])
919                                 }
920                         }
921                 })
922         }
923 }
924
925 var memclrSink []int8
926
927 func BenchmarkMemclrKnownSize1(b *testing.B) {
928         var x [1]int8
929
930         b.SetBytes(1)
931         for i := 0; i < b.N; i++ {
932                 for a := range x {
933                         x[a] = 0
934                 }
935         }
936
937         memclrSink = x[:]
938 }
939 func BenchmarkMemclrKnownSize2(b *testing.B) {
940         var x [2]int8
941
942         b.SetBytes(2)
943         for i := 0; i < b.N; i++ {
944                 for a := range x {
945                         x[a] = 0
946                 }
947         }
948
949         memclrSink = x[:]
950 }
951 func BenchmarkMemclrKnownSize4(b *testing.B) {
952         var x [4]int8
953
954         b.SetBytes(4)
955         for i := 0; i < b.N; i++ {
956                 for a := range x {
957                         x[a] = 0
958                 }
959         }
960
961         memclrSink = x[:]
962 }
963 func BenchmarkMemclrKnownSize8(b *testing.B) {
964         var x [8]int8
965
966         b.SetBytes(8)
967         for i := 0; i < b.N; i++ {
968                 for a := range x {
969                         x[a] = 0
970                 }
971         }
972
973         memclrSink = x[:]
974 }
975 func BenchmarkMemclrKnownSize16(b *testing.B) {
976         var x [16]int8
977
978         b.SetBytes(16)
979         for i := 0; i < b.N; i++ {
980                 for a := range x {
981                         x[a] = 0
982                 }
983         }
984
985         memclrSink = x[:]
986 }
987 func BenchmarkMemclrKnownSize32(b *testing.B) {
988         var x [32]int8
989
990         b.SetBytes(32)
991         for i := 0; i < b.N; i++ {
992                 for a := range x {
993                         x[a] = 0
994                 }
995         }
996
997         memclrSink = x[:]
998 }
999 func BenchmarkMemclrKnownSize64(b *testing.B) {
1000         var x [64]int8
1001
1002         b.SetBytes(64)
1003         for i := 0; i < b.N; i++ {
1004                 for a := range x {
1005                         x[a] = 0
1006                 }
1007         }
1008
1009         memclrSink = x[:]
1010 }
1011 func BenchmarkMemclrKnownSize112(b *testing.B) {
1012         var x [112]int8
1013
1014         b.SetBytes(112)
1015         for i := 0; i < b.N; i++ {
1016                 for a := range x {
1017                         x[a] = 0
1018                 }
1019         }
1020
1021         memclrSink = x[:]
1022 }
1023
1024 func BenchmarkMemclrKnownSize128(b *testing.B) {
1025         var x [128]int8
1026
1027         b.SetBytes(128)
1028         for i := 0; i < b.N; i++ {
1029                 for a := range x {
1030                         x[a] = 0
1031                 }
1032         }
1033
1034         memclrSink = x[:]
1035 }
1036
1037 func BenchmarkMemclrKnownSize192(b *testing.B) {
1038         var x [192]int8
1039
1040         b.SetBytes(192)
1041         for i := 0; i < b.N; i++ {
1042                 for a := range x {
1043                         x[a] = 0
1044                 }
1045         }
1046
1047         memclrSink = x[:]
1048 }
1049
1050 func BenchmarkMemclrKnownSize248(b *testing.B) {
1051         var x [248]int8
1052
1053         b.SetBytes(248)
1054         for i := 0; i < b.N; i++ {
1055                 for a := range x {
1056                         x[a] = 0
1057                 }
1058         }
1059
1060         memclrSink = x[:]
1061 }
1062
1063 func BenchmarkMemclrKnownSize256(b *testing.B) {
1064         var x [256]int8
1065
1066         b.SetBytes(256)
1067         for i := 0; i < b.N; i++ {
1068                 for a := range x {
1069                         x[a] = 0
1070                 }
1071         }
1072
1073         memclrSink = x[:]
1074 }
1075 func BenchmarkMemclrKnownSize512(b *testing.B) {
1076         var x [512]int8
1077
1078         b.SetBytes(512)
1079         for i := 0; i < b.N; i++ {
1080                 for a := range x {
1081                         x[a] = 0
1082                 }
1083         }
1084
1085         memclrSink = x[:]
1086 }
1087 func BenchmarkMemclrKnownSize1024(b *testing.B) {
1088         var x [1024]int8
1089
1090         b.SetBytes(1024)
1091         for i := 0; i < b.N; i++ {
1092                 for a := range x {
1093                         x[a] = 0
1094                 }
1095         }
1096
1097         memclrSink = x[:]
1098 }
1099 func BenchmarkMemclrKnownSize4096(b *testing.B) {
1100         var x [4096]int8
1101
1102         b.SetBytes(4096)
1103         for i := 0; i < b.N; i++ {
1104                 for a := range x {
1105                         x[a] = 0
1106                 }
1107         }
1108
1109         memclrSink = x[:]
1110 }
1111 func BenchmarkMemclrKnownSize512KiB(b *testing.B) {
1112         var x [524288]int8
1113
1114         b.SetBytes(524288)
1115         for i := 0; i < b.N; i++ {
1116                 for a := range x {
1117                         x[a] = 0
1118                 }
1119         }
1120
1121         memclrSink = x[:]
1122 }