模式 01: 内核中常见的性能优化方法
1. 批量处理
add_to_page_cache_lru
, 操作lru的话, 先放到per cpu的lru cache (struct pagevec), 待lru cache存满后drain.
2. 吞吐量(Throughput)和时延(Latency)
2.1 HZ 设置为 250, 1000等.
2.2 中断线程化后, 吞吐量可能下降, 但系统其它地方的时延可能改善.
3. 用空间换时间
计算结果缓存之类的, 比如 一些数值计算, 开根号什么的.
4. 收敛?
radix tree的tag, 不必逐个判断该节点 子树 下的叶子. 这个可能也可以归到 缓存 中.
hash应该也算这个类别.
5. 缓存
buddy system 一开始从zone的链表中分配, 释放时放到per cpu的pcp, 后续从pcp中取, 减少了锁的问题.
6. 锁的问题
6.1 使用per cpu. 比如 lru问题 per cpu的 pagevec.
6.2
1. lock全局的链表,
2. 从全局的链表中挑选放入on a local list,
3. unlock 全局的链表
4. 对 local list进行相对比较耗时的操作
这个比较常见, 比如 ...
6.3 RCU的适用范围 ...
6.4 把相关信息 挤到 int 中, 更新int是原子的, 就省掉了锁. 比如, strct page中有:
struct { /* SLUB */
unsigned inuse:16;
unsigned objects:15;
unsigned frozen:1;
};
7. offload
网卡: TSO, GRO 等
DMA
8. poll 改成 回调
poll的写法:
check_and_run()
{
for each item //不管是否ready
if (item.check_ready())
do something for item
}
如果 要检查的item非常多, 可能出现很多都不是ready状态, 这样, 会浪费不少时间在检查上.
改成回调的形式:
某个时机, 添加item到ready队列中.
run_ready_item()
{
for each one in ready queue
do something for item
}
本文地址: https://awakening-fong.github.io/posts/other/optimize
转载请注明出处: https://awakening-fong.github.io
若无法评论, 请打开JavaScript, 并通过proxy.
blog comments powered by Disqus