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  }