在合理避免不必要的锁之外,还有什么办法可以提高性能呢?
最近写了一个熔断器,但是因为统计数据,URL 匹配等地方都需要加锁来使用(因为要面临并发修改数据的情况)。所以性能大概是 Nginx 的 3/5 左右。
目前能想到的是缩小锁的粒度。但是预计性能提升不会太大。
请问还有什么好办法可以规避锁的使用吗?
求方法 or 资料,非常感谢!
1
paw 2018-01-12 18:46:14 +08:00
如果只是为了统计数据,简单的全局变量++的话,原子变量
如果涉及梗复杂的结构,比如 map<somekey, uint64_t>这种,要先查再++的,做成每线程变量指向每线程独立的 map 结构,在需要统计的时候用指针交换的方式来拿到每线程的 map 做统计再释放。 |
2
paw 2018-01-12 18:47:50 +08:00
///没写完接上面
这样代码层面就完全无锁了。 但是原子变量会锁总线的,要是这个也想避免,就都用每线程变量指向一个 struct 进行++; |
3
paw 2018-01-12 18:50:17 +08:00
妈蛋。纠正上面名词不对 。 每线程变量 >> 线程局部变量(Thread Local Variable)
|
4
WuwuGin 2018-01-12 18:56:25 +08:00 via Android
统计数据需要锁很少见吧,除非你真的需要精确到原子级和具体数据,建议换个思路放弃锁。
|
5
secondwtq 2018-01-12 19:12:46 +08:00 via iPhone
Is Parallel Programming Hard? And If So, What can you do about it? 这书里面一开始就讲了 counting problem
|
6
cloudzhou 2018-01-12 19:14:07 +08:00
先说语言
|
7
paw 2018-01-12 20:12:06 +08:00
如果 LZ 是 nginx 插件形式开发的,忽略我 1-3 楼的回答,我简单的吧场景想象成了单进程多线程的。
能详细描述下你的开发场景吗???? |
8
herozem OP |
9
cloudzhou 2018-01-12 23:36:32 +08:00
如果 https://golang.org/pkg/sync/atomic/ 还不能满足,那你要思考整个设计了
另一个方式,局部本地变量累加,统计的时候汇总计算 |
11
herozem OP @cloudzhou 有用 pprof 分析的,虽然 topN 最前面的是 runtime 里的例如 defer,我自己写的代码里比较靠前的就是锁的相关操作了。统计这块应该可以用 channel 改造
|
12
ryd994 2018-01-14 22:47:35 +08:00 via Android
线程内各自统计,定时汇总
|