/
main.go
127 lines (105 loc) · 2.3 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"flag"
"fmt"
"os"
"runtime"
"runtime/pprof"
"syscall"
"time"
"github.com/ii64/gouring"
)
var fs = flag.NewFlagSet("perf", flag.ExitOnError)
var (
entries uint
sqPoll bool
sqThreadCpu uint
sqThreadIdle uint
N uint
noti uint
pprofCpuFilename = "pprof.cpu"
)
func init() {
fs.UintVar(&entries, "entries", 256, "Entries")
fs.BoolVar(&sqPoll, "sqpoll", false, "Enable SQPOLL")
fs.UintVar(&sqThreadCpu, "sqthreadcpu", 16, "SQ Thread CPU")
fs.UintVar(&sqThreadIdle, "sqthreadidle", 10_000, "SQ Thread idle") // milliseconds
fs.UintVar(&N, "n", 10_000, "N times")
fs.UintVar(¬i, "noti", 10_000, "Notify per attempt N")
fs.StringVar(&pprofCpuFilename, "pprofCpu", pprofCpuFilename, "pprof cpu output file")
}
func main() {
err := fs.Parse(os.Args[1:])
if err != nil {
panic(err)
}
// check entries size
if entries > uint(^uint32(0)) {
panic("entries overflow.")
}
params := &gouring.IoUringParams{}
if sqPoll {
params.Flags |= gouring.IORING_SETUP_SQPOLL
params.SqThreadCpu = uint32(sqThreadCpu)
params.SqThreadIdle = uint32(sqThreadIdle)
}
h, err := gouring.NewWithParams(uint32(entries), params)
if err != nil {
panic(err)
}
defer h.Close()
f, err := os.Create(pprofCpuFilename)
if err != nil {
panic(err)
}
fmt.Println("performing...")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
var i, j uint
var sqe *gouring.IoUringSqe
var cqe *gouring.IoUringCqe
var submitted int
startTime := time.Now()
for i = 0; i < N; i++ {
if i%noti == 0 { // notify
fmt.Printf("n:%d e:%s\n", j, time.Now().Sub(startTime))
}
for j = 0; j < entries; j++ {
for {
// sqe could be nil if SQ is already full so we spin until we got one
sqe = h.GetSqe()
if sqe != nil {
break
}
runtime.Gosched()
}
gouring.PrepNop(sqe)
sqe.UserData.SetUint64(uint64(i + j))
}
submitted, err = h.Submit()
if err != nil {
panic(err)
}
if i%noti == 0 { // notify
fmt.Printf(" >> submitted %d\n", submitted)
}
for j = 0; j < entries; j++ {
err = h.WaitCqe(&cqe)
if err == syscall.EINTR {
continue
}
if err != nil {
panic(err)
}
if cqe == nil {
panic("cqe is nil!")
}
if cqe.Res < 0 {
panic(syscall.Errno(-cqe.Res))
}
h.SeenCqe(cqe)
}
}
_ = submitted
_ = err
}