Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use goroutine pool to avoid the runtime.newstack call #637

Merged
merged 8 commits into from
Dec 14, 2022

Conversation

tiancaiamao
Copy link
Contributor

close #630

Benchmark program

package main

import (
	"context"
	"database/sql"
	"flag"
	"fmt"
	"log"
	"time"
	"sync/atomic"

	"github.com/jamiealquiza/tachymeter"
	_ "github.com/go-sql-driver/mysql"
)

var (
	host     = flag.String("h", "127.0.0.1", "host")
	port     = flag.Int("P", 4000, "port")
	user     = flag.String("u", "root", "username")
	password = flag.String("p", "", "password")
)

func openDB() (*sql.DB, error) {
	dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/test", *user, *password, *host, *port)
	db, err := sql.Open("mysql", dbDSN)
	if err != nil {
		return nil, err
	}
	return db, nil
}

func mustExec(db *sql.DB, query string, args ...interface{}) {
	_, err := db.Exec(query, args...)
	if err != nil {
		log.Fatal(err)
	}
}

func assert(err error) {
	if err != nil {
		log.Fatal(err)
	}
}	

func main() {
	flag.Parse()
	db, err := openDB()
	if err != nil {
		log.Fatal(err)
	}

	mustExec(db, `use test`)
	mustExec(db, `drop table if exists test;`)
	mustExec(db, `create table test (id int unsigned key nonclustered auto_increment) shard_row_id_bits=4 auto_id_cache 1;`)

	t := tachymeter.New(&tachymeter.Config{Size: 300})
	var count int64

	now := time.Now()
	fmt.Println("benchmark start ...")

	for i := 0; i < 64; i++ {
		go func() {
			conn, err := db.Conn(context.Background())
			assert(err)

			_, err = conn.ExecContext(context.Background(), "use test")
			assert(err)

			for {
				start := time.Now()
				_, err := conn.ExecContext(context.Background(), "insert into test values ()")
				assert(err)
				atomic.AddInt64(&count, 1)
				t.AddTime(time.Since(start))
			}
		}()
	}


	tick := time.NewTicker(5 * time.Second)
	for range tick.C {
		total := atomic.LoadInt64(&count)
		fmt.Println("qps ==", total/5)
		atomic.StoreInt64(&count, 0)

		fmt.Println(t.Calc())
		fmt.Println()
	}


	fmt.Println("benchmark end ...", time.Since(now))
}

After this change, the runtime.newstack -> runtime.copystack disappear.

image

Signed-off-by: tiancaiamao <tiancaiamao@gmail.com>
Signed-off-by: tiancaiamao <tiancaiamao@gmail.com>
Signed-off-by: tiancaiamao <tiancaiamao@gmail.com>
Signed-off-by: tiancaiamao <tiancaiamao@gmail.com>
Signed-off-by: tiancaiamao <tiancaiamao@gmail.com>
Signed-off-by: tiancaiamao <tiancaiamao@gmail.com>
@tiancaiamao
Copy link
Contributor Author

PTAL @disksing

@sticnarf
Copy link
Collaborator

sticnarf commented Dec 9, 2022

@tiancaiamao Would you please add an Apache-compatible license to your project tiancaiamao/gp?

@sticnarf
Copy link
Collaborator

sticnarf commented Dec 9, 2022

You pointed out the problem in #630 that the goroutine started in startWorker enlarged the stack. But why using goroutine in doActionOnGroupMutations solves the problem in this PR?

Signed-off-by: tiancaiamao <tiancaiamao@gmail.com>
@tiancaiamao
Copy link
Contributor Author

@tiancaiamao Would you please add an Apache-compatible license to your project tiancaiamao/gp?

Done

@tiancaiamao
Copy link
Contributor Author

You pointed out the problem in #630 that the goroutine started in startWorker enlarged the stack. But why using goroutine in doActionOnGroupMutations solves the problem in this PR?

It's startWorker.func1 which is actually this closure function (closure function is named func1 func2 etc) @sticnarf

@sticnarf sticnarf merged commit 809eb2d into tikv:master Dec 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

There are room for performance improvement here
2 participants