smoltcp-rs / smoltcp

a smol tcp/ip stack
BSD Zero Clause License
3.64k stars 404 forks source link

so bad performance, echo example is very slow? #795

Closed centny closed 1 year ago

centny commented 1 year ago

start server

try 1: defautl code resuts if

image

try 2: change rx/tx buffer to 65535

    let tcp2_rx_buffer = tcp::SocketBuffer::new(vec![0; 65535]);
    let tcp2_tx_buffer = tcp::SocketBuffer::new(vec![0; 65535]);
image

try 3: disable reverse data

            let data = socket
                .recv(|buffer| {
                    let recvd_len = buffer.len();
                    let mut data = buffer.to_owned();
                    // if !data.is_empty() {
                    //     debug!("tcp:6970 recv data: {:?}", data);
                    //     data = data.split(|&b| b == b'\n').collect::<Vec<_>>().concat();
                    //     data.reverse();
                    //     data.extend(b"\n");
                    // }
                    (recvd_len, data)
                })
                .unwrap();
image

try 4: only recv

            let data = socket
                .recv(|buffer| {
                    let recvd_len = buffer.len();
                    let mut data = buffer.to_owned();
                    // if !data.is_empty() {
                    //     debug!("tcp:6970 recv data: {:?}", data);
                    //     data = data.split(|&b| b == b'\n').collect::<Vec<_>>().concat();
                    //     data.reverse();
                    //     data.extend(b"\n");
                    // }
                    (recvd_len, data)
                })
                .unwrap();
            // if socket.can_send() && !data.is_empty() {
            //     debug!("tcp:6970 send data: {:?}", data);
            //     socket.send_slice(&data[..]).unwrap();
            // }
image

try 5: --release

image

the test client code

package main

import (
    "fmt"
    "net"
    "os"
    "time"
)

func speedConn(conn net.Conn, action string) (err error) {
    buf := make([]byte, 8*1024)
    n := 0
    lastAll := []int64{}
    lastTime := time.Now()
    lastBytes := int64(0)

    for {
        if action == "R" {
            n, err = conn.Read(buf)
        } else {
            n, err = conn.Write(buf)
        }
        if err != nil {
            break
        }
        lastBytes += int64(n)
        if time.Since(lastTime) > time.Second {
            lastAll = append(lastAll, lastBytes)
            if len(lastAll) > 5 {
                lastAll = lastAll[1:]
            }
            lastBytes = 0
            lastTime = time.Now()
            lastTotal := int64(0)
            for _, v := range lastAll {
                lastTotal += v
            }
            lastAvg := lastTotal / int64(len(lastAll))
            if lastAvg > 1024*1024*1024 {
                fmt.Printf("%v %v GB/s\n", action, float64(lastAvg)/1024/1024/1024)
            } else if lastAvg > 1024*1024 {
                fmt.Printf("%v %v MB/s\n", action, float64(lastAvg)/1024/1024)
            } else if lastAvg > 1024 {
                fmt.Printf("%v %v KB/s\n", action, float64(lastAvg)/1024)
            } else {
                fmt.Printf("%v %v B/s\n", action, float64(lastAvg))
            }
        }
    }
    return
}

func main() {
    conn, err := net.Dial("tcp", os.Args[1])
    if err != nil {
        panic(err)
    }
    go speedConn(conn, "W")
    speedConn(conn, "R")
}
Dirbaio commented 1 year ago

Compile with --release.

centny commented 1 year ago

@Dirbaio try it, better

image
Dirbaio commented 1 year ago

my results:

trying the same on 6971, which only receives:

[dirbaio@mars smoltcp]$ go run test.go 192.168.69.1:6971
W 655.328125 MB/s
W 628.37890625 MB/s
W 620.4973955154419 MB/s
W 605.966796875 MB/s
W 599.6374998092651 MB/s
W 584.1624994277954 MB/s

That's approx ~5gbit. It's about the performance to be expected out of a tun/tap interface, these are somewhat inefficient because they require a system call for each packet. If you check with perf, a lot of the CPU time is spent entering/exiting syscalls:

screenshot-2023-06-09_12-51-42

Laptop with i7-8850H, Linux 6.3.4-arch2-1.

centny commented 1 year ago

@Dirbaio thinks. it is ok, try compare it with lwip. it is better performance to lwip. may be the vm server problem.