wa-lang.org/wazero@v1.0.2/internal/engine/compiler/compiler_bench_test.go (about) 1 package compiler 2 3 import ( 4 "bytes" 5 "fmt" 6 "testing" 7 "unsafe" 8 9 "wa-lang.org/wazero/internal/wasm" 10 "wa-lang.org/wazero/internal/wazeroir" 11 ) 12 13 func BenchmarkCompiler_compileMemoryCopy(b *testing.B) { 14 sizes := []uint32{5, 17, 128, 10000, 64000} 15 16 for _, size := range sizes { 17 for _, overlap := range []bool{false, true} { 18 b.Run(fmt.Sprintf("%v-%v", size, overlap), func(b *testing.B) { 19 env := newCompilerEnvironment() 20 21 mem := env.memory() 22 testMem := make([]byte, len(mem)) 23 for i := 0; i < len(mem); i++ { 24 mem[i] = byte(i) 25 testMem[i] = byte(i) 26 } 27 28 compiler, _ := newCompiler(&wazeroir.CompilationResult{HasMemory: true, Signature: &wasm.FunctionType{}}, false) 29 err := compiler.compilePreamble() 30 requireNoError(b, err) 31 32 var destOffset, sourceOffset uint32 33 if !overlap { 34 destOffset, sourceOffset = 1, 777 35 } else { 36 destOffset, sourceOffset = 777, 1 37 } 38 39 err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: destOffset}) 40 requireNoError(b, err) 41 err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: sourceOffset}) 42 requireNoError(b, err) 43 err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: size}) 44 requireNoError(b, err) 45 err = compiler.compileMemoryCopy() 46 requireNoError(b, err) 47 err = compiler.(compilerImpl).compileReturnFunction() 48 requireNoError(b, err) 49 code, _, err := compiler.compile() 50 requireNoError(b, err) 51 52 env.execBench(b, code) 53 54 for i := 0; i < b.N; i += 1 { 55 copy(testMem[destOffset:destOffset+size], testMem[sourceOffset:sourceOffset+size]) 56 } 57 58 if !bytes.Equal(mem, testMem) { 59 b.FailNow() 60 } 61 }) 62 } 63 } 64 } 65 66 func BenchmarkCompiler_compileMemoryFill(b *testing.B) { 67 sizes := []uint32{5, 17, 128, 10000, 64000} 68 69 for _, size := range sizes { 70 b.Run(fmt.Sprintf("%v", size), func(b *testing.B) { 71 env := newCompilerEnvironment() 72 73 mem := env.memory() 74 testMem := make([]byte, len(mem)) 75 for i := 0; i < len(mem); i++ { 76 mem[i] = byte(i) 77 testMem[i] = byte(i) 78 } 79 80 compiler, _ := newCompiler(&wazeroir.CompilationResult{HasMemory: true, Signature: &wasm.FunctionType{}}, false) 81 err := compiler.compilePreamble() 82 requireNoError(b, err) 83 84 var startOffset uint32 = 100 85 var value uint8 = 5 86 87 err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: startOffset}) 88 requireNoError(b, err) 89 err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: uint32(value)}) 90 requireNoError(b, err) 91 err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: size}) 92 requireNoError(b, err) 93 err = compiler.compileMemoryFill() 94 requireNoError(b, err) 95 err = compiler.(compilerImpl).compileReturnFunction() 96 requireNoError(b, err) 97 code, _, err := compiler.compile() 98 requireNoError(b, err) 99 100 env.execBench(b, code) 101 102 for i := startOffset; i < startOffset+size; i++ { 103 testMem[i] = value 104 } 105 if !bytes.Equal(mem, testMem) { 106 b.FailNow() 107 } 108 }) 109 } 110 } 111 112 func (j *compilerEnv) execBench(b *testing.B, codeSegment []byte) { 113 b.StartTimer() 114 for i := 0; i < b.N; i++ { 115 nativecall( 116 uintptr(unsafe.Pointer(&codeSegment[0])), 117 uintptr(unsafe.Pointer(j.ce)), 118 uintptr(unsafe.Pointer(j.moduleInstance)), 119 ) 120 } 121 b.StopTimer() 122 } 123 124 func requireNoError(b *testing.B, err error) { 125 if err != nil { 126 b.Fatal(err) 127 } 128 }