[go-nuts] Why is the cpu usage so high in a golang tcp server?

2017-12-18 Thread Sokolov Yura
You didn't buffer writes.
libevent does a good job at buffer managment. Go's net.Conn and os.File are 
unbuffered, ie they are almost "raw" file descriptors. You should use 
bufio.Writer and bufio.Reader, or make buffering by hands. (Just don't forget 
to flush bufio.Writer if response channel is empty)

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Why is the cpu usage so high in a golang tcp server?

2017-12-18 Thread eric . shen881027


I try to implement a golang tcp server, and I found the concurrency is 
satisfied for me, but the CPU usage is too high(concurrency is 15W+/s, but 
the CPU usage is about 800% in a 24 cores linux machine). At the same time, 
a C++ tcp server is only about 200% usage with a similar concurrency(with 
libevent).

The following code is the demo of golang:

func main() {
listen, err := net.Listen("tcp", "0.0.0.0:17379")
if err != nil {
fmt.Errorf(err.Error())
}
go acceptClient(listen)
var channel2 = make(chan bool)
<-channel2}

func acceptClient(listen net.Listener) {
for {
sock, err := listen.Accept()
if err != nil {
fmt.Errorf(err.Error())
}
tcp := sock.(*net.TCPConn)
tcp.SetNoDelay(true)
var channel = make(chan bool, 10)
go read(channel, sock.(*net.TCPConn))
go write(channel, sock.(*net.TCPConn))
}}

func read(channel chan bool, sock *net.TCPConn) {
count := 0
for {
var buf = make([]byte, 1024)
n, err := sock.Read(buf)
if err != nil {
close(channel)
sock.CloseRead()
return
}
count += n
x := count / 58
count = count % 58
for i := 0; i < x; i++ {
channel <- true
}
   }}

func write(channel chan bool, sock *net.TCPConn) {
buf := []byte("+OK\r\n")
defer func() {
sock.CloseWrite()
recover()
}()
for {
_, ok := <-channel
if !ok {
return
}
_, writeError := sock.Write(buf)
if writeError != nil {
return
}
}}

And I test this tcp server by the redis-benchmark with multi-clients:

redis-benchmark -h 10.100.45.2  -p 17379 -n 1000 -q script load 
"redis.call('set','aaa','aaa')"

I also analyzed my golang code by the pprof, it is said CPU cost a lot of time 
on syscall:




-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.