Skip to content

Conversation

@Fangliding
Copy link
Member

@Fangliding Fangliding commented Dec 11, 2025

减少滥用 runtime.Gosched() (在有buffer的情况下几乎每次write执行一次 对go调度器压力很大)
在土制小测试中可以让 mux cool 的复制效率提升大概 100% 不过test是双端一起的 不知道对服务端的提升大不大

不知道这样稍微改变一点点行为会不会影响别的part

@Fangliding
Copy link
Member Author

这个不重要 我好像发现从8.3到8.29之间让回环测试暴跌了将近一半

@Fangliding

This comment was marked as outdated.

@Fangliding
Copy link
Member Author

Fangliding commented Dec 12, 2025

似乎来自 这个timeout太重了
56a45ad

@RPRX
Copy link
Member

RPRX commented Dec 12, 2025

似乎来自 这个timeout太重了 56a45ad

ReadMultiBufferTimeout() 只会被调用一次吧,ReadMultiBuffer() 看起来也不重啊,r.done 就是 nil,是不是开流量统计了?

func (r *TimeoutWrapperReader) ReadMultiBuffer() (MultiBuffer, error) {
if r.done != nil {
<-r.done
r.done = nil
if r.Counter != nil {
r.Counter.Add(int64(r.mb.Len()))
}
return r.mb, r.err
}
r.mb, r.err = r.Reader.ReadMultiBuffer()
if r.Counter != nil {
r.Counter.Add(int64(r.mb.Len()))
}
return r.mb, r.err
}

@Fangliding
Copy link
Member Author

那可能是猜错了
可以知道 func (w *BufferToBytesWriter) WriteMultiBuffer(mb MultiBuffer) error 这个函数收到的都是长度为1的buffer 所以调用了 WriteAllBytes 没看到 writev 函数调用 其实本质是 WriteMultiBuffer 的caller莫名其妙从可以给几个buffer全部变成了给一个

@Fangliding
Copy link
Member Author

总之确实是从这个版本开始掉了一堆速度 那堆commit里没什么改buffer行为的 就这个commit了

@Fangliding
Copy link
Member Author

也可能是中间那个buffer管道没了导致的 可能这个buffer有点必要

@yuhan6665
Copy link
Member

po 下变慢的 回环测试 看看?

@Fangliding
Copy link
Member Author

Fangliding commented Dec 14, 2025

po 下变慢的 回环测试 看看?

这个测试是 curl 拉 speed.cloudflare.com 已经吃满 100% CPU 了 很确定就是那个commit的问题 我已经重编译试过了 客户端问题

@Fangliding
Copy link
Member Author

是write方向是因为这是客户端socks5 write回curl

@yuhan6665
Copy link
Member

我在 v2rayng 上实测了一下 socks outbound -> 电脑端 socks in freedom out -> iperf3
上行下行都试了
速度都能拉到wifi上限(我的wifi较慢)貌似最新版比8月份的版本 cpu 占用还低一点。。
是不是跟测试数据有关?

@Fangliding
Copy link
Member Author

Fangliding commented Dec 14, 2025

我在 v2rayng 上实测了一下 socks outbound -> 电脑端 socks in freedom out -> iperf3 上行下行都试了 速度都能拉到wifi上限(我的wifi较慢)貌似最新版比8月份的版本 cpu 占用还低一点。。 是不是跟测试数据有关?

我的问题 没说清楚
我的测试是都在VPS上 服务端vless入+freedom出 客户端socks5入+vless出 传输方式websocket (跟ws有关?)

再仔细看了一下 调用链出在vless outbound的getResponse的buf.Copy的write方向

@Fangliding
Copy link
Member Author

好像是这样
ws用的SingleReader(只读一个buffer出来)
旧版本中间套了一层pipe 它内部有缓冲 所以最后往底层连接写入的时候 一次系统调用写入了多块buffer
新版本中间商pipe被剥掉了 SingleReader 和 net.Conn 直接对接 导致一次系统调用只write了一块buffer 最终导致了吞吐量下降

看来有时候没有中间商赚差价反而会导致速度变慢

@yuhan6665
Copy link
Member

可以 我稍候在我这个setup试下vless ws

@Fangliding
Copy link
Member Author

就是这个问题 我试了一下通过非常反模式的方法解决writev问题的话速度就可以回去 甚至比8.3还要快(以非常dirty的方法向量化了整个SingleRrader带来的提升?)

@yuhan6665
Copy link
Member

客户端 Android 服务端 Windows iperf3 怎么测都是新版好一点。。

download 平均 313 Mbits/sec --- cpu 占用
vless ws mux off v25.12.2 --- 3%
vless ws mux on v25.12.2 --- 7%
vless ws mux off fcdd4df Aug 28 --- 7%
vless ws mux on fcdd4df Aug 28 --- 9%

upload 325 Mbits/sec --- cpu 占用
vless ws mux off v25.12.2 --- 1.5%
vless ws mux on v25.12.2 --- 4%
vless ws mux off fcdd4df Aug 28 --- 3%
vless ws mux on fcdd4df Aug 28 --- 4%

要不你把你那边测试最优的发个 build 我再试试

@yuhan6665
Copy link
Member

再看一眼数据 似乎 download 总是 upload 的两倍 cpu。。是哪里拷贝了两次吗?

@Fangliding
Copy link
Member Author

那很奇怪了
我是两边都放在vps上然后curl拉http://speed.cloudflare.com/__down?bytes=1000000000 试一下完全复刻这个场景?
还是说Android没有writev(?)

@Fangliding
Copy link
Member Author

Fangliding commented Dec 15, 2025

可以观察一下最后往conn是不是一个write一个writev
image
image

@yuhan6665
Copy link
Member

Screenshot205003 有 writev 的 也确实是用 cpu 最多的地方 另外说一嘴 以前以为在 v2rayng 上 pprof 很麻烦 这次试了一下发现配置很方便 给 yichya Fangliding 佬点个赞

@Fangliding
Copy link
Member Author

你这里面还有pipe调用 似乎是来自mux 把mux关了试试

@yuhan6665
Copy link
Member

我试了一下老版和新版 真的 call stack 不一样!之前po的是老版有 writev
profilenomuxold

新版是 write
profilenomuxnew

@Fangliding
Copy link
Member Author

对了 这个pr本身还是ready to merge的 测试了可以用 热循环里Gosched()肯定不对

@Fangliding
Copy link
Member Author

Fangliding commented Dec 21, 2025

@yuhan6665
把pipe复制过来不现实(它强依赖buf包) 我自己写了一个 gather 然后试了下应用上去 这样应该可以优化所有SingleReader
旧版本 40MB/s
新版本 20MB/s
修复后 50MB/s
的样子

@qwerttvv
Copy link

可以合并了吧

@yuhan6665
Copy link
Member

加入了测试结果:我这个带宽太小所以数值过低 不太严谨 但是可以确认新版 copyv 有提升

download 313 Mbits/sec
vless ws mux off copyv 2%
vless ws mux on copyv 5%
vless ws mux off v25.12.2 3%
vless ws mux on v25.12.2 7%
vless ws mux off fcdd4df Aug 28 7%
vless ws mux on fcdd4df Aug 28 9%

upload 325 Mbits/sec
vless ws mux off copyv 1.5%
vless ws mux on copyv 4%
vless ws mux off v25.12.2 1.5%
vless ws mux on v25.12.2 4%
vless ws mux off fcdd4df Aug 28 3%
vless ws mux on fcdd4df Aug 28 4%

我看了一下代码 我觉得 4mb 在有些场景还是挺大的 我们加个 env var ?

@Fangliding
Copy link
Member Author

是我记错默认的pipe buffer了 现在没问题了 从policy拿bufferSize然后除上8192算出channel buffer size

@yuhan6665
Copy link
Member

简单测试了下 无问题

@RPRX
Copy link
Member

RPRX commented Dec 23, 2025

那就先合了吧

@RPRX RPRX merged commit 81bef3d into main Dec 23, 2025
78 checks passed
Fangliding added a commit that referenced this pull request Dec 23, 2025
@Fangliding
Copy link
Member Author

刚发现一点小问题 我先把主线滚回去了 让我再看一下()

@Fangliding
Copy link
Member Author

@RPRX @yuhan6665
之前这个PR有一个小地方敲错了导致copyv实际没有生效
不过真的修之后又有问题了 似乎有地方确实要求copy是1:1的 我这么操作之后似乎会mux cool卡住 我还没找出来为啥(
我已经试过把copyv的应用范围缩小到一个地方了(vless出站getResponse) 还是炸了

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.

5 participants