Skip to content

Commit

Permalink
wip move from other branch
Browse files Browse the repository at this point in the history
  • Loading branch information
deelawn committed May 10, 2024
1 parent a03eeb3 commit 0ea751f
Show file tree
Hide file tree
Showing 14 changed files with 404 additions and 0 deletions.
107 changes: 107 additions & 0 deletions benchmarking/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package main

import (
"encoding/binary"
"flag"
"fmt"
"os"
"sync"

"github.com/gnolang/gno/benchmarking"
"github.com/gnolang/gno/gnovm/pkg/gnolang"
)

const recordSize int = 10

var pathFlag = flag.String("path", "", "the path to the benchmark file")

func main() {
flag.Parse()

file, err := os.Open(*pathFlag)
if err != nil {
panic("could not create benchmark file: " + err.Error())
}
defer file.Close()

inputCh := make(chan []byte, 10000)
outputCh := make(chan string, 10000)
wg := sync.WaitGroup{}
numWorkers := 1
wg.Add(numWorkers)

doneCh := make(chan struct{})

for i := 0; i < numWorkers; i++ {
go func() {
for {
record, ok := <-inputCh
if !ok {
break
}

opName := gnolang.Op(record[0]).String()
if record[1] != 0 {
opName = benchmarking.StoreCodeString(record[1])
}

elapsedTime := binary.LittleEndian.Uint32(record[2:])
size := binary.LittleEndian.Uint32(record[6:])
outputCh <- opName + "," + fmt.Sprint(elapsedTime) + "," + fmt.Sprint(size)
}
wg.Done()
}()
}

go func() {
out, err := os.Create("results.csv")
if err != nil {
panic("could not create readable output file: " + err.Error())
}
defer out.Close()
fmt.Fprintln(out, "op,elapsedTime,diskIOBytes")

for {
output, ok := <-outputCh
if !ok {
break
}

fmt.Fprintln(out, output)
}

out.Close()
doneCh <- struct{}{}
}()

var i int

bufSize := recordSize * 100000
buf := make([]byte, bufSize)

for {
nbytes, err := file.Read(buf)

if err != nil && nbytes == 0 {
break
}
n := nbytes / recordSize

for j := 0; j < n; j++ {
inputCh <- buf[j*recordSize : (j+1)*recordSize]
}

i += bufSize / recordSize
if i%1000 == 0 {
fmt.Println(i)
}
}

close(inputCh)
wg.Wait()
close(outputCh)
<-doneCh
close(doneCh)

fmt.Println("done")
}
46 changes: 46 additions & 0 deletions benchmarking/exporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package benchmarking

import (
"encoding/binary"
"fmt"
"os"
"time"
)

var fileWriter *exporter

func initExporter(fileName string) {
file, err := os.Create(fileName)
if err != nil {
panic("could not create benchmark file: " + err.Error())

Check warning on line 15 in benchmarking/exporter.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/exporter.go#L12-L15

Added lines #L12 - L15 were not covered by tests
}

fileWriter = &exporter{
file: file,

Check warning on line 19 in benchmarking/exporter.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/exporter.go#L18-L19

Added lines #L18 - L19 were not covered by tests
}
}

type exporter struct {
file *os.File
}

func (e *exporter) export(code Code, elapsedTime time.Duration, size uint32) {
buf := []byte{code[0], code[1], 0, 0, 0, 0, 0, 0, 0, 0}
binary.LittleEndian.PutUint32(buf[2:], uint32(elapsedTime))
binary.LittleEndian.PutUint32(buf[6:], size)
_, err := e.file.Write(buf)
if err != nil {
panic("could not write to benchmark file: " + err.Error())

Check warning on line 33 in benchmarking/exporter.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/exporter.go#L27-L33

Added lines #L27 - L33 were not covered by tests
}
}

func (e *exporter) close() {
e.file.Sync()
e.file.Close()

Check warning on line 39 in benchmarking/exporter.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/exporter.go#L37-L39

Added lines #L37 - L39 were not covered by tests
}

func Finish() {
fmt.Println("## StackSize: ", stackSize)

Check warning on line 43 in benchmarking/exporter.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/exporter.go#L42-L43

Added lines #L42 - L43 were not covered by tests

fileWriter.close()

Check warning on line 45 in benchmarking/exporter.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/exporter.go#L45

Added line #L45 was not covered by tests
}
6 changes: 6 additions & 0 deletions benchmarking/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package benchmarking

func Init(filepath string) {
initExporter(filepath)
initStack()

Check warning on line 5 in benchmarking/init.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/init.go#L3-L5

Added lines #L3 - L5 were not covered by tests
}
37 changes: 37 additions & 0 deletions benchmarking/measurement.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package benchmarking

import (
"time"
)

type measurement struct {
*timer
code Code
allocation uint32
}

func startNewMeasurement(code Code) *measurement {
return &measurement{
timer: &timer{startTime: time.Now()},
code: code,

Check warning on line 16 in benchmarking/measurement.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/measurement.go#L13-L16

Added lines #L13 - L16 were not covered by tests
}
}

func (m *measurement) pause() {
m.stop()

Check warning on line 21 in benchmarking/measurement.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/measurement.go#L20-L21

Added lines #L20 - L21 were not covered by tests
}

func (m *measurement) resume() {
m.start()

Check warning on line 25 in benchmarking/measurement.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/measurement.go#L24-L25

Added lines #L24 - L25 were not covered by tests
}

func (m *measurement) end(size uint32) {
m.stop()
if size != 0 && m.allocation != 0 {
panic("measurement cannot have both allocation and size")
} else if size == 0 {
size = m.allocation

Check warning on line 33 in benchmarking/measurement.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/measurement.go#L28-L33

Added lines #L28 - L33 were not covered by tests
}

fileWriter.export(m.code, m.elapsedTime, size)

Check warning on line 36 in benchmarking/measurement.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/measurement.go#L36

Added line #L36 was not covered by tests
}
62 changes: 62 additions & 0 deletions benchmarking/ops.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package benchmarking

// store code
const (
StoreGetObject byte = 0x01 // get value and unmarshl to object from store
StoreSetObject byte = 0x02 // marshal object and set value in store
StoreDeleteObject byte = 0x03 // delete value from store
StoreGetPackage byte = 0x04 // get package from store
StoreSetPackage byte = 0x05 // get package from store
StoreGetType byte = 0x06 // get type from store
StoreSetType byte = 0x07 // set type in store
StoreGetBlockNode byte = 0x08 // get block node from store
StoreSetBlockNode byte = 0x09 // set block node in store
StoreAddMemPackage byte = 0x0A // add mempackage to store
StoreGetMemPackage byte = 0x0B // get mempackage from store
FinalizeTx byte = 0x0C // finalize realm transaction

AminoMarshal byte = 0x0D // marshal go object to binary value
AminoUnMarshal byte = 0x0E // unmarshl binary value to go object

StoreGet byte = 0x0F // Get binary value by key
StoreSet byte = 0x10 // Set binary value by key

invalidStoreCode string = "StoreInvalid"
)

var storeCodeNames = []string{
invalidStoreCode,
"StoreGetObject",
"StoreSetObject",
"StoreDeleteObject",
"StoreGetPackage",
"StoreSetPackage",
"StoreGetType",
"StoreSetType",
"StoreGetBlockNode",
"StoreSetBlockNode",
"StoreAddMemPackage",
"StoreGetMemPackage",
"FinalizeTx",
"AminoMarshal",
"AminoUnMarshal",
"StoreGet",
"StoreSet",
}

type Code [2]byte

func VMOpCode(opCode byte) Code {
return [2]byte{opCode, 0x00}

Check warning on line 50 in benchmarking/ops.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/ops.go#L49-L50

Added lines #L49 - L50 were not covered by tests
}

func StoreCode(storeCode byte) Code {
return [2]byte{0x00, storeCode}

Check warning on line 54 in benchmarking/ops.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/ops.go#L53-L54

Added lines #L53 - L54 were not covered by tests
}

func StoreCodeString(storeCode byte) string {
if int(storeCode) >= len(storeCodeNames) {
return invalidStoreCode

Check warning on line 59 in benchmarking/ops.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/ops.go#L57-L59

Added lines #L57 - L59 were not covered by tests
}
return storeCodeNames[storeCode]

Check warning on line 61 in benchmarking/ops.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/ops.go#L61

Added line #L61 was not covered by tests
}
5 changes: 5 additions & 0 deletions benchmarking/ops_disabled.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//go:build !benchmarkingops

package benchmarking

const OpsEnabled = false
5 changes: 5 additions & 0 deletions benchmarking/ops_enabled.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//go:build benchmarkingops

package benchmarking

const OpsEnabled = true
66 changes: 66 additions & 0 deletions benchmarking/stack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package benchmarking

const initStackSize int = 64

var (
measurementStack []*measurement
stackSize int
)

func initStack() {
measurementStack = make([]*measurement, initStackSize)

Check warning on line 11 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L10-L11

Added lines #L10 - L11 were not covered by tests
}

func StartMeasurement(code Code) {
if stackSize != 0 {
measurementStack[stackSize-1].pause()

Check warning on line 16 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L14-L16

Added lines #L14 - L16 were not covered by tests
}

if stackSize == len(measurementStack) {
newStack := make([]*measurement, stackSize*2)
copy(newStack, measurementStack)
measurementStack = newStack

Check warning on line 22 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L19-L22

Added lines #L19 - L22 were not covered by tests
}

measurementStack[stackSize] = startNewMeasurement(code)
stackSize++

Check warning on line 26 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L25-L26

Added lines #L25 - L26 were not covered by tests
}

// Pause pauses current measurement on the stack
func Pause() {
if stackSize != 0 {
measurementStack[stackSize-1].pause()

Check warning on line 32 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L30-L32

Added lines #L30 - L32 were not covered by tests
}
}

// Resume resumes current measurement on the stack
func Resume() {
if stackSize != 0 {
measurementStack[stackSize-1].resume()

Check warning on line 39 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L37-L39

Added lines #L37 - L39 were not covered by tests
}
}

// StopMeasurement ends the current measurement and resumes the previous one
// if one exists. It accepts the number of bytes that were read/written to/from
// the store. This value is zero if the operation is not a read or write.
func StopMeasurement(size uint32) {
if stackSize == 0 {
return

Check warning on line 48 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L46-L48

Added lines #L46 - L48 were not covered by tests
}

measurementStack[stackSize-1].end(size)

Check warning on line 51 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L51

Added line #L51 was not covered by tests

stackSize--

Check warning on line 53 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L53

Added line #L53 was not covered by tests

if stackSize != 0 {
measurementStack[stackSize-1].resume()

Check warning on line 56 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L55-L56

Added lines #L55 - L56 were not covered by tests
}
}

func RecordAllocation(size uint32) {
if stackSize == 0 {
return

Check warning on line 62 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L60-L62

Added lines #L60 - L62 were not covered by tests
}

measurementStack[stackSize-1].allocation += size

Check warning on line 65 in benchmarking/stack.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/stack.go#L65

Added line #L65 was not covered by tests
}
5 changes: 5 additions & 0 deletions benchmarking/storage_disabled.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//go:build !benchmarkingstorage

package benchmarking

const StorageEnabled = false
5 changes: 5 additions & 0 deletions benchmarking/storage_enabled.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//go:build benchmarkingstorage

package benchmarking

const StorageEnabled = true
22 changes: 22 additions & 0 deletions benchmarking/timer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package benchmarking

import "time"

type timer struct {
startTime time.Time
elapsedTime time.Duration
isStopped bool
}

func (t *timer) start() {
t.startTime = time.Now()

Check warning on line 12 in benchmarking/timer.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/timer.go#L11-L12

Added lines #L11 - L12 were not covered by tests
}

func (t *timer) stop() {
if t.isStopped {
return

Check warning on line 17 in benchmarking/timer.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/timer.go#L15-L17

Added lines #L15 - L17 were not covered by tests
}

t.elapsedTime += time.Since(t.startTime)
t.isStopped = true

Check warning on line 21 in benchmarking/timer.go

View check run for this annotation

Codecov / codecov/patch

benchmarking/timer.go#L20-L21

Added lines #L20 - L21 were not covered by tests
}
5 changes: 5 additions & 0 deletions gno.land/cmd/gnoland/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"time"

bm "github.com/gnolang/gno/benchmarking"
"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/gno.land/pkg/log"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
Expand Down Expand Up @@ -201,6 +202,10 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) {
}

func execStart(c *startCfg, io commands.IO) error {
if bm.OpsEnabled || bm.StorageEnabled {
bm.Init("benchmarks.bin")

Check warning on line 206 in gno.land/cmd/gnoland/start.go

View check run for this annotation

Codecov / codecov/patch

gno.land/cmd/gnoland/start.go#L206

Added line #L206 was not covered by tests
}

// Get the absolute path to the node's data directory
nodeDir, err := filepath.Abs(c.dataDir)
if err != nil {
Expand Down
Loading

0 comments on commit 0ea751f

Please sign in to comment.