Files
wazero/internal/engine/compiler/compiler_bench_test.go
2022-12-20 12:49:47 +09:00

129 lines
3.3 KiB
Go

package compiler
import (
"bytes"
"fmt"
"testing"
"unsafe"
"github.com/tetratelabs/wazero/internal/wasm"
"github.com/tetratelabs/wazero/internal/wazeroir"
)
func BenchmarkCompiler_compileMemoryCopy(b *testing.B) {
sizes := []uint32{5, 17, 128, 10000, 64000}
for _, size := range sizes {
for _, overlap := range []bool{false, true} {
b.Run(fmt.Sprintf("%v-%v", size, overlap), func(b *testing.B) {
env := newCompilerEnvironment()
mem := env.memory()
testMem := make([]byte, len(mem))
for i := 0; i < len(mem); i++ {
mem[i] = byte(i)
testMem[i] = byte(i)
}
compiler := newCompiler()
compiler.Init(&wazeroir.CompilationResult{HasMemory: true, Signature: &wasm.FunctionType{}}, false)
err := compiler.compilePreamble()
requireNoError(b, err)
var destOffset, sourceOffset uint32
if !overlap {
destOffset, sourceOffset = 1, 777
} else {
destOffset, sourceOffset = 777, 1
}
err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: destOffset})
requireNoError(b, err)
err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: sourceOffset})
requireNoError(b, err)
err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: size})
requireNoError(b, err)
err = compiler.compileMemoryCopy()
requireNoError(b, err)
err = compiler.(compilerImpl).compileReturnFunction()
requireNoError(b, err)
code, _, err := compiler.compile()
requireNoError(b, err)
env.execBench(b, code)
for i := 0; i < b.N; i += 1 {
copy(testMem[destOffset:destOffset+size], testMem[sourceOffset:sourceOffset+size])
}
if !bytes.Equal(mem, testMem) {
b.FailNow()
}
})
}
}
}
func BenchmarkCompiler_compileMemoryFill(b *testing.B) {
sizes := []uint32{5, 17, 128, 10000, 64000}
for _, size := range sizes {
b.Run(fmt.Sprintf("%v", size), func(b *testing.B) {
env := newCompilerEnvironment()
mem := env.memory()
testMem := make([]byte, len(mem))
for i := 0; i < len(mem); i++ {
mem[i] = byte(i)
testMem[i] = byte(i)
}
compiler := newCompiler()
compiler.Init(&wazeroir.CompilationResult{HasMemory: true, Signature: &wasm.FunctionType{}}, false)
var startOffset uint32 = 100
var value uint8 = 5
err := compiler.compileConstI32(&wazeroir.OperationConstI32{Value: startOffset})
requireNoError(b, err)
err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: uint32(value)})
requireNoError(b, err)
err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: size})
requireNoError(b, err)
err = compiler.compileMemoryFill()
requireNoError(b, err)
err = compiler.(compilerImpl).compileReturnFunction()
requireNoError(b, err)
code, _, err := compiler.compile()
requireNoError(b, err)
env.execBench(b, code)
for i := startOffset; i < startOffset+size; i++ {
testMem[i] = value
}
if !bytes.Equal(mem, testMem) {
b.FailNow()
}
})
}
}
func (j *compilerEnv) execBench(b *testing.B, codeSegment []byte) {
b.StartTimer()
for i := 0; i < b.N; i++ {
nativecall(
uintptr(unsafe.Pointer(&codeSegment[0])),
uintptr(unsafe.Pointer(j.ce)),
uintptr(unsafe.Pointer(j.moduleInstance)),
)
}
b.StopTimer()
}
func requireNoError(b *testing.B, err error) {
if err != nil {
b.Fatal(err)
}
}