惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security @ Cisco Blogs
罗磊的独立博客
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
T
The Blog of Author Tim Ferriss
美团技术团队
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
博客园 - Franky
G
Google Developers Blog
Jina AI
Jina AI
Stack Overflow Blog
Stack Overflow Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
V
Visual Studio Blog
腾讯CDC
S
SegmentFault 最新的问题
Recent Announcements
Recent Announcements
博客园 - 叶小钗
Microsoft Security Blog
Microsoft Security Blog
雷峰网
雷峰网
L
LangChain Blog
Vercel News
Vercel News
Forbes - Security
Forbes - Security
PCI Perspectives
PCI Perspectives
N
News | PayPal Newsroom
S
Security Affairs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
J
Java Code Geeks
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Hacker News: Ask HN
Hacker News: Ask HN
Schneier on Security
Schneier on Security
A
About on SuperTechFans
Attack and Defense Labs
Attack and Defense Labs
Google Online Security Blog
Google Online Security Blog
aimingoo的专栏
aimingoo的专栏
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
Cloudbric
Cloudbric
B
Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
D
DataBreaches.Net
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog RSS Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News and Events Feed by Topic

重归混沌的BLOG

给silly实现了一个ernro模块 | 重归混沌的BLOG 给silly实现了一个ernro模块 | 重归混沌的BLOG 第一次在生产环境使用 Vibe Coding | 重归混沌的BLOG 第一次在生产环境使用 Vibe Coding | 重归混沌的BLOG API 设计的艰难抉择 | 重归混沌的BLOG API 设计的艰难抉择 | 重归混沌的BLOG 十年 | 重归混沌的BLOG 十年 | 重归混沌的BLOG 在Go语言中如何使XML加载内存无限趋近于0 | 重归混沌的BLOG 在Go语言中如何使XML加载内存无限趋近于0 | 重归混沌的BLOG 对跨服玩法中的分布式一致性问题进行简单抽象 | 重归混沌的BLOG 对跨服玩法中的分布式一致性问题进行简单抽象 | 重归混沌的BLOG Go语言逃逸分析之slice和map | 重归混沌的BLOG Go语言逃逸分析之slice和map | 重归混沌的BLOG 谈谈观测 | 重归混沌的BLOG 谈谈观测 | 重归混沌的BLOG 写了个AI Agent服务端 | 重归混沌的BLOG 写了个AI Agent服务端 | 重归混沌的BLOG 谈谈代码设计中“严丝合缝” | 重归混沌的BLOG 谈谈代码设计中“严丝合缝” | 重归混沌的BLOG 一次艰难的线上游戏服务器内存排查经历 | 重归混沌的BLOG 一次艰难的线上游戏服务器内存排查经历 如何基于LanguageServerProtocol来编写lint工具 谈谈游戏服务器中RPC模块的设计 谈谈游戏服务器代码抽象 最近碰到的一个分布式一致性问题 谈谈游戏服务器的自动化测试 对Raft协议的一点理解 使用mmap来学习/proc/pid/smaps 2023(完) 再次实现了一个Lua性能分析器 终于给Silly的定时器增加了取消功能 一次虚拟内存排查经历 游戏服务器分布式数据的一种同步的思路 为silly增加了互斥锁 2022(完) Go语言之闭包篇 一例误用unsafe包引起的内存问题 Go语言之内存篇 初识Go语言 重新抽象图形API 给Lua实现了一个数学库 谈谈跨平台图形API的抽象 寻路和Flocking算法的结合 行为树的一种高效实现 内测过程中Shader出现的问题 彻底解决多国语言 谈谈数据库的选型 再谈Lua热更新(终) 初窥Rust 关于游戏服务器的服务拆分 ECS的初步实现 ECS初探 屏幕空间(SreenSpace)的想象力 一些对辐射度量学的理解 深度缓冲和半透明渲染 Mysql的间隙锁 更新一些GPU相关知识 2020 地形渲染之爬过的坑 Lua5.3 GC源码阅读(5) 实现一个数据库存储队列 再学计算机图形学入门 再谈分布式服务架构 游戏上线一个月后的反思 一次并发Bug 双向链表的三种实现 谈谈随机数的使用 再谈性能优化 2019 Lua中的函数式编程 重构登录逻辑 Unity资源管理(续) 谈谈Unity的资源管理 一次关于Cache的性能分析 历史之2018 DC3算法 移动平台native代码遭遇的坑 从CPU层面谈谈优化 开卷有益(UNIX编程艺术篇) GC竞争问题 通过Mesh投影来实现贴花系统 谈谈我对数据同步的理解 又一个类型提升引起的Bug Lua5.3 GC源码阅读(4) Lua5.3 GC源码阅读(3) Lua5.3 GC源码阅读(2) Lua5.3 GC源码阅读(1) 三角形光栅化时遇到的坑 一次git事故 再见2017 又一个lua调试器 客户端缓存落地方案 Paxos算法 HTTP服务器的特点 关于CPU分支预测 C程序中让两个不同版本的库共存 实现了一个AOI模块 一个高可伸缩的游戏服务器架构 关于网络协议封装的一些新想法
一次性能优化经历
重归混沌 · 2017-09-23 · via 重归混沌的BLOG

自从上次修改backlog之后, Silly的IO能力,就一直以少量(约4~6K)的差距落后于redis,却一直找不到原因。

这次打算从头做一次profile来问题到底出在哪。

先用GNU提供的gprof分析一下C代码是否有值得优化的地方,结果发现CPU使用率最高的地方是luaVM内部和malloc/free。

我们所有的业务逻辑全在lua层做的,而IO线程与worker(lua)线程进行交互时是通过malloc来实现的。这几乎表明C代码几乎已经没有优化的余地了。

但是有个好消息,就是gprof不去profile系统调用和so,也许还有机会。

压测时,先使用top看一下每个cpu core的使用率,包括用户态与内核态。

用户态过高一般是应用逻辑代码消耗的,内核态则有可能是因为系统调用过多,上下文切换过频繁,等其他原因。

不过top只能看到当时的cpu状态,不太好看出整个测试区间,cpu消耗的曲线。可以改用’sar -u -P ALL 1’每隔一秒打印出cpu的使用情况。

通过观察发现,有一个线程的内核态有70+%之多,相比Redis来讲高出不少。

再使用vmstat命令查看in(系统中断)/cs(上下文切换), 可以确认在整个压测区间in和cs显著升高,推测应该是系统调用造成的。

为了近一步确认这些‘中断和上下文切换’是由Silly造成的,使用’pidstat -w -p PID 1’来打印出某一个线程的上下文切换频率。

当确认之后,再使用’strace -p $PID -c -f’来收集此进程所有系统调用次数。再根据收集到的信息有针对性的优化。

如果以上都做了,还是没有什么可以优化的余地。没关系,我们还有一个神器perf来查看Cache命中率,分支预测失败率,CPU调度迁移等与cpu密切相关的信息。

如果以上都已经做还是没有找到优化空间。

还有一个很常见但很容易被人忽略的因素,就是CPU的用户态和内核态都很低。

这种情况下,一般是程序或集群间有队列(这个队列可能是socket等一切有FIFO性质的设施),队列的一端处理过慢(比如由于某种原因,处理端被卡住了,而又不耗cpu) ,而队列的产生端在产生完请求之后,由于一直没有收到回应,也一直在idle中。

整个表现,看上去特别诡异,就像是突然间机器空载了一样。


最后,当我们发现应用层代码实在无法优化之后,别着急,也许还有最后几个免费午餐你还没有吃。

jemalloc

一款很优秀的内存分配器,即使对多线程也有很好的表现。以此次优化silly为例,把内存分配器换成jemalloc 5.0之后,请求处理速度有显著提升。

__builtin_expect

GNU内建函数,可以用来向GCC暗示哪个分支更高概率的被执行,以便GCC可以生成更好的代码,以方便CPU做分支预测。当我们的分支判断成功与失败的概率有显著差别时(比如异常处理),可以用来提高性能,至于能提高多少,要看具体情况。其中一种情况的测如见上篇

cpu affinity

linux内核向应用程序提供了一些接口,可以让我们微调内核,包括调度算法。cpu affinity可以修改进程或线程的cpu亲和力。以暗示内核,最少可能选成cpu迁移,cpu迁移数据可以通过perf工具来获取。