github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/memmove_test.go (about)

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