github.com/moontrade/wavm-go@v0.3.2-0.20220316110326-d229dd66ad65/worker/loader_test.go (about) 1 package worker 2 3 import ( 4 "os" 5 "runtime" 6 "testing" 7 "time" 8 9 "github.com/moontrade/wavm-go" 10 ) 11 12 var ( 13 file []byte 14 fileObject []byte 15 fileWASM []byte 16 ) 17 18 func init() { 19 if runtime.GOOS == "darwin" { 20 if runtime.GOARCH == "arm64" { 21 file, _ = os.ReadFile("testdata/main.darwin_arm64") 22 fileObject, _ = os.ReadFile("testdata/main_object.darwin_arm64") 23 } else if runtime.GOARCH == "amd64" { 24 file, _ = os.ReadFile("testdata/main.darwin_amd64") 25 fileObject, _ = os.ReadFile("testdata/main_object.darwin_amd64") 26 } 27 } else if runtime.GOOS == "linux" { 28 file, _ = os.ReadFile("testdata/main.linux_amd64") 29 fileObject, _ = os.ReadFile("testdata/main_object.linux_amd64") 30 } 31 fileWASM, _ = os.ReadFile("testdata/main.wasm") 32 } 33 34 func BenchmarkCGO(b *testing.B) { 35 b.Run("cgo unsafe", func(b *testing.B) { 36 b.ReportAllocs() 37 for i := 0; i < b.N; i++ { 38 stub_fast() 39 } 40 }) 41 b.Run("cgo", func(b *testing.B) { 42 b.ReportAllocs() 43 for i := 0; i < b.N; i++ { 44 stub_safe() 45 } 46 }) 47 } 48 49 func BenchmarkClock(b *testing.B) { 50 //nanos := tsc.UnixNano() 51 //println("monotonic", nanos, time.UnixMicro(nanos/1000).String()) 52 53 b.Run("time.Now()", func(b *testing.B) { 54 for i := 0; i < b.N; i++ { 55 time.Now().UnixNano() 56 } 57 }) 58 59 //b.Run("tsc.UnixNano()", func(b *testing.B) { 60 // for i := 0; i < b.N; i++ { 61 // tsc.UnixNano() 62 // } 63 //}) 64 65 b.Run("runtime.nanoTime", func(b *testing.B) { 66 for i := 0; i < b.N; i++ { 67 runtimeNano() 68 } 69 }) 70 71 b.Run("cgo now", func(b *testing.B) { 72 for i := 0; i < b.N; i++ { 73 now() 74 } 75 }) 76 } 77 78 func TestCompile(t *testing.T) { 79 engine := wavm.NewEngine() 80 buf := engine.Compile(fileWASM, nil) 81 println("precompiled module", len(buf)) 82 os.WriteFile("testdata/main.darwin_arm64", buf, 0755) 83 84 buf = engine.CompileObject(fileWASM, buf) 85 println("object", len(buf)) 86 os.WriteFile("testdata/main_object.darwin_arm64", buf, 0755) 87 } 88 89 func BenchmarkCompile(b *testing.B) { 90 buf := make([]byte, 128000) 91 engine := wavm.NewEngine() 92 93 b.ResetTimer() 94 b.ReportAllocs() 95 for i := 0; i < b.N; i++ { 96 buf = engine.Compile(fileWASM, buf) 97 _ = buf 98 } 99 } 100 101 func TestLoader(t *testing.T) { 102 runtime.LockOSThread() 103 defer runtime.UnlockOSThread() 104 105 loader := NewLoader(DefaultEngine) 106 worker, err := loader.Load(true, true, file) 107 if err != nil { 108 t.Fatal(err) 109 } 110 111 //Resume(worker) 112 err = worker.Start() 113 if err != nil { 114 t.Fatal(err) 115 } 116 println("start took", time.Duration(worker.end-worker.begin).String()) 117 118 // Cache the Thunk 119 _ = worker.Call(worker.stub) 120 start := time.Now() 121 err = worker.Call(worker.stub) 122 if err != nil { 123 t.Fatal(err) 124 } 125 println("stub_safe took", time.Now().Sub(start).String()) 126 127 _ = worker.Close() 128 time.Sleep(time.Second) 129 } 130 131 func BenchmarkLoader(b *testing.B) { 132 b.Run("Precompiled", func(b *testing.B) { 133 loader := NewLoader(DefaultEngine) 134 b.ResetTimer() 135 b.ReportAllocs() 136 for i := 0; i < b.N; i++ { 137 worker, err := loader.Load(true, false, file) 138 if err != nil { 139 b.Fatal(err) 140 } 141 _ = worker 142 _ = worker.Close() 143 } 144 b.StopTimer() 145 _ = loader.Close() 146 }) 147 148 b.Run("Object", func(b *testing.B) { 149 loader := NewLoader(DefaultEngine) 150 b.ResetTimer() 151 b.ReportAllocs() 152 for i := 0; i < b.N; i++ { 153 worker, err := loader.Load(true, false, file) 154 if err != nil { 155 b.Fatal(err) 156 } 157 _ = worker 158 _ = worker.Close() 159 } 160 b.StopTimer() 161 _ = loader.Close() 162 }) 163 } 164 165 func BenchmarkStub(b *testing.B) { 166 var ( 167 testRawBaseline = false 168 ) 169 b.Run("Copy and Trap", func(b *testing.B) { 170 //runtime.LockOSThread() 171 //defer runtime.UnlockOSThread() 172 loader := NewLoader(DefaultEngine) 173 worker, err := loader.Load(true, false, file) 174 err = worker.Call(worker.stub) 175 b.ResetTimer() 176 b.ReportAllocs() 177 for i := 0; i < b.N; i++ { 178 err = worker.Call(worker.stub) 179 if err != nil { 180 b.Fatal(err) 181 } 182 } 183 b.StopTimer() 184 _ = loader.Close() 185 }) 186 b.Run("No Copy", func(b *testing.B) { 187 runtime.LockOSThread() 188 defer runtime.UnlockOSThread() 189 loader := NewLoader(DefaultEngine) 190 worker, err := loader.Load(true, false, file) 191 err = worker.CallNoCopy(worker.stub) 192 b.ResetTimer() 193 b.ReportAllocs() 194 for i := 0; i < b.N; i++ { 195 err = worker.CallNoCopy(worker.stub) 196 if err != nil { 197 b.Fatal(err) 198 } 199 } 200 b.StopTimer() 201 _ = loader.Close() 202 }) 203 b.Run("No Trap", func(b *testing.B) { 204 runtime.LockOSThread() 205 defer runtime.UnlockOSThread() 206 loader := NewLoader(DefaultEngine) 207 worker, err := loader.Load(true, false, file) 208 err = worker.CallNoTrap(worker.stub) 209 b.ResetTimer() 210 b.ReportAllocs() 211 for i := 0; i < b.N; i++ { 212 err = worker.CallNoTrap(worker.stub) 213 if err != nil { 214 b.Fatal(err) 215 } 216 } 217 b.StopTimer() 218 _ = loader.Close() 219 }) 220 b.Run("No Copy and No Trap", func(b *testing.B) { 221 runtime.LockOSThread() 222 defer runtime.UnlockOSThread() 223 loader := NewLoader(DefaultEngine) 224 worker, err := loader.Load(true, false, file) 225 err = worker.CallNoCopyNoTrap(worker.stub) 226 _, _ = worker, err 227 b.ResetTimer() 228 b.ReportAllocs() 229 for i := 0; i < b.N; i++ { 230 //stub_safe() 231 err = worker.CallNoCopyNoTrap(worker.stub) 232 //if err != nil { 233 // b.Fatal(err) 234 //} 235 } 236 b.StopTimer() 237 _ = loader.Close() 238 }) 239 240 if testRawBaseline { 241 b.Run("Default No CGO", func(b *testing.B) { 242 runtime.LockOSThread() 243 defer runtime.UnlockOSThread() 244 loader := NewLoader(DefaultEngine) 245 worker, _ := loader.Load(true, false, file) 246 b.ResetTimer() 247 b.ReportAllocs() 248 moontrade_benchmark_stub(worker, b.N) 249 b.StopTimer() 250 _ = loader.Close() 251 }) 252 b.Run("Default No CGO No Copy", func(b *testing.B) { 253 runtime.LockOSThread() 254 defer runtime.UnlockOSThread() 255 loader := NewLoader(DefaultEngine) 256 worker, _ := loader.Load(true, false, file) 257 b.ResetTimer() 258 b.ReportAllocs() 259 moontrade_benchmark_stub_no_copy(worker, b.N) 260 b.StopTimer() 261 _ = loader.Close() 262 }) 263 b.Run("Default No CGO No Trap", func(b *testing.B) { 264 runtime.LockOSThread() 265 defer runtime.UnlockOSThread() 266 loader := NewLoader(DefaultEngine) 267 worker, _ := loader.Load(true, false, file) 268 b.ResetTimer() 269 b.ReportAllocs() 270 moontrade_benchmark_stub_no_trap(worker, b.N) 271 b.StopTimer() 272 _ = loader.Close() 273 }) 274 b.Run("Default No CGO No Copy No Trap", func(b *testing.B) { 275 runtime.LockOSThread() 276 defer runtime.UnlockOSThread() 277 loader := NewLoader(DefaultEngine) 278 worker, _ := loader.Load(true, false, file) 279 b.ResetTimer() 280 b.ReportAllocs() 281 moontrade_benchmark_stub_no_copy_no_trap(worker, b.N) 282 b.StopTimer() 283 _ = loader.Close() 284 }) 285 } 286 } 287 288 func BenchmarkLoadModule(b *testing.B) { 289 engine := wavm.NewEngine() 290 b.Run("WASM", func(b *testing.B) { 291 for i := 0; i < b.N; i++ { 292 wavm.NewModule(engine, fileWASM) 293 } 294 }) 295 296 b.Run("Compiled", func(b *testing.B) { 297 for i := 0; i < b.N; i++ { 298 wavm.NewModulePrecompiled(engine, file) 299 } 300 }) 301 }