mirror of
https://github.com/openlibrecommunity/olcrtc.git
synced 2026-06-02 06:23:37 +02:00
perf: optimize write polling and kcp interval for lower latency
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -81,14 +82,26 @@ func (c *Conn) Read(p []byte) (int, error) {
|
||||
// Write encrypts p and ships it to the link as a single message. Blocks while
|
||||
// the link signals back-pressure.
|
||||
func (c *Conn) Write(p []byte) (int, error) {
|
||||
for {
|
||||
// Spin briefly first - on a healthy link CanSend usually clears within
|
||||
// well under a millisecond, so a 10ms sleep adds visible per-frame
|
||||
// latency to interactive request/response traffic. Fall back to a
|
||||
// modest sleep only if the link is truly congested.
|
||||
const (
|
||||
fastSpinAttempts = 200
|
||||
slowPollDelay = 2 * time.Millisecond
|
||||
)
|
||||
for attempt := 0; ; attempt++ {
|
||||
if c.isClosed() {
|
||||
return 0, ErrClosed
|
||||
}
|
||||
if c.ln.CanSend() {
|
||||
break
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
if attempt < fastSpinAttempts {
|
||||
runtime.Gosched()
|
||||
continue
|
||||
}
|
||||
time.Sleep(slowPollDelay)
|
||||
}
|
||||
|
||||
enc, err := c.cipher.Encrypt(p)
|
||||
|
||||
@@ -65,11 +65,14 @@ func startKCP(out chan<- []byte, onData func([]byte), epochHdr [epochHdrLen]byte
|
||||
return nil, fmt.Errorf("kcp new conn: %w", err)
|
||||
}
|
||||
|
||||
// Aggressive ARQ tuning: nodelay=1, interval=10ms, fast resend=2, no
|
||||
// congestion control. This is the standard "turbo" preset used by KCP
|
||||
// tunnels on lossy networks (shadowsocks, kcptun) and is the whole point
|
||||
// of choosing KCP over SCTP.
|
||||
sess.SetNoDelay(1, 10, 2, 1)
|
||||
// Aggressive ARQ tuning: nodelay=1, interval=5ms, fast resend=2, no
|
||||
// congestion control. The 5ms tick (vs the kcptun-default 10ms) halves
|
||||
// the worst-case scheduling latency in each direction, which matters a
|
||||
// lot for interactive workloads (SOCKS5 + HTTP request needs ~3 RTTs
|
||||
// before the first byte of the response shows up). Below 5ms the
|
||||
// CPU cost of the KCP update loop starts climbing without much
|
||||
// additional latency benefit.
|
||||
sess.SetNoDelay(1, 5, 2, 1)
|
||||
sess.SetWindowSize(kcpSndWnd, kcpRcvWnd)
|
||||
sess.SetMtu(kcpMTU)
|
||||
sess.SetACKNoDelay(true)
|
||||
|
||||
Reference in New Issue
Block a user