是想考 monotonic time 和 wall time 吗?
也可能是想考 vdso 的 syscall
memory order,golang doc 里并没有和 c艹对比? issue 里有提到 Go 的 memory order 等同于 seq_cst 反而好写 lockfree 程序,因为在 seq_cst 的内存模型下,原子操作的 load 和 store 之间可以保证线性的执行关系。只不过性能差一些,不知道作者说的需要解决的问题是啥问题?
相关 issue 在这里:这里
是想考 lock contention 和 read lock 的 cache contention?
对锁进行优化一般思路是进行锁的粒度拆分。
runtime 里的优化手段一般是按照 p 来进行拆分,比如 timer bucket 的拆分。内存分配时每个 p 上都有各种乱七八糟的 cache,本地获取基本可以无锁,获取不到的时候,才会进全局抢锁,思路都差不多。
用户态无法获得 p.id
,但可以进行简单的锁粒度拆分,类似 github 上开源的 concurrentmap,或者 sync.Map 的实现。一些场景可以尝试用 atomic.CAS 替代读写锁。
不会扩栈的死循环在触发 GC 的时候都有可能有问题。1.13 开始引入基于信号的调度。
列出下面操作延迟数量级(1ms, 10us或100ns等),cgo 调用 c 代码,c 调用 go 代码,channel在单线程单 case 的 select 中被选中,high contention 下对未满的 buffered channel 的写延迟。
cgo 基本是几十~100ns 级别。
其它需要 bench 一下
如何设计实现一个简单的 goroutine leak 检测库,可用于在测试运行结束后打印出所测试程序泄露的 goroutine 的 stacktrace 以及 goroutine 被创建的文件名和行号。
参考 pingcap 的小哥们跑测试前检查一次所有的 g,跑完之后检查一次。然后类似 pprof 可以把全局所有的 g 的 stack 打出来,把那些多出来的 g 的 stack 打印出来应该就行了。
同时 select 很多 channel 的时候,并发较高时会有性能问题。因为 select 本质是按 chan 地址排序,顺序加锁。lock1->lock2->lock3->lock4
活跃 goroutine 数量较多时,会导致全局的延迟不可控。比如 99 分位惨不忍睹。
slice append 的时候可能触发扩容,初始 cap 不合适会有大量 growSlice。
map hash collision,会导致 overflow bucket 很长,但这种基本不太可能,hash seed 每次启动都是随机的。此外,map 中 key value 超过 128 字节时,会被转为 indirectkey 和 indirectvalue,会对 GC 的扫描阶段造成压力,如果 k v 多,则扫描的 stw 就会很长。
sync.Map 有啥性能问题?写多读少的时候?
一个 C/C++ 程序需要调用一个 go 库,某一 export 了的 go 函数需高频率调用,且调用间隔需要调用根据 go 函数的返回调用其它C/C++函数处理,无法改变调用次序、相互依赖关系的前提下,如何最小化这样高频调用的性能损耗?
放弃治疗,用 go 重写
不知道。但我觉得提问者是想炫耀自己看过这个文档:numa-aware go scheduler。既然这么了解,那为啥提问者不给官方提个 proposal 并且把这个功能实现了呢?说不定还能进 Go 官方开发组哦~
看不出来想考什么。
gc 的触发频率和 stw 时间和系统类型业务逻辑强相关。作者的这个 100us 也不准确,比如我们这里的就是 1ms stw。
可能出问题的:
map 元素中有大量的指针。
请求 qps 突增,导致堆上的小对象太多。sync.Pool 简单重用就好,虽然 sync.Pool 也比较挫。
gcwaiting 阶段,有 g 一直不退出。
已经做了充分优化。要降低 GC 开销。。。。。感觉逻辑有问题呢
把能变成值类型的指针类型全变掉减小 gc scan 开销么?不知道想考什么。
或者 GOGC=off 弃疗,手动狗头
sync.Pool 在每次 gc 时都会清理掉所有对象,在 1.13 之前没什么好办法。
具体的区别还是需要 bench 一下。
为何只有一个 time.Sleep(time.Millisecond) 循环的 go 程序 CPU 占用显著高于同类C/C++程序?或请详述只有一个 goroutine 的 Go 程序,每次 time.Sleep(time.Millisecond) 调用 runtime 所发生的事情。
time.Sleep requires 7 syscalls,官方有 issue 来说明这件事情:这里
C++ 的 time.Sleep 具体操作之后补充~
原作者在知乎上给出了其遇到的场景,https://zhuanlan.zhihu.com/p/45959147
不知道,need test
pprof 的 cpuprofile 火焰图
启动时传入环境变量 Debug=gctrace
go tool trace,可以看到 p 绑定的 g 实际的 GC 动作和相应时长,以及阻塞时间
一般情况下是 = NumCPU,后续版本官方都计划把这个选项干掉了,不知道提问者问这个问题有什么意义。
一个成熟完备久经优化的 Golang 后台系统,程序只有一个进程,由 golang 实现。其核心处理的部分由数十个 goroutine 负责处理数万 goroutine 发起的请求。由于无法设定 goroutine 调度优先级,使得核心处理的那数十个 goroutine 往往无法及时被调度得到 CPU,进而影响了处理的延迟。有什么改进办法?
参考毛毛哥答案,把发任务和处理任务拆进程。
很多,有的很扯。
比如 1.9 的时候 http 库的作者自己改代码的时候也没有做 benchmark。
个人感觉考这个也没啥意义,翻翻每个版本的更新日志和官方的 benchmark 就能看到,可能提问者是想看看应聘人是否一直在跟进 Go 本身的更新。