golang 内敛策略

相关配置

  • 禁止内连
    • 单个函数禁止内连在函数定义前一行添加//go:noinline;
    • -gcflags="-l"选项全局禁用内联
    • -gcflags=“all=-N -l” 代表的是表示主模块和它所有的依赖都禁用【编译器优化】和【内联】
    • marked “go:norace” and -race compilation,
    • marked “go:nocheckptr” and -d checkptr compilation,
    • marked “go:cgo_unsafe_args”,
    • marked as “go:uintptrkeepalive”
    • If marked as “go:uintptrescapes”
    • Yeswritebarrierrec
    • a local function has no fn.Body

判断函数是否可以 inline :
* -gflags=“-m” 显示被内连的函数
* -gflags=“-m -m” 显示原因
* -gcflags=“-d pctab=pctoinline” 显示内敛映射表

内连(inlining)

内连是编译期间的优化,将调用函数的地方直接替换为函数本身(空间换时间),从而减少执行时的跳转操作。golang 编译器默认进行该优化。

内连策略

核心思想是函数足够简单,通过如下条件来定义 简单:

src/cmd/compile/internal/inline/inl.go
CanInline() determines whether fn is inlineable
InlineImpossible() 有具体的判断流程

  1. 函数足够简单,当解析AST时,Go申请了80个节点作为内联的预算。每个节点都会消耗一个预算。函数的开销不能超过这个预算;

  2. 不能包含闭包,defer,recover,select;

  3. 不能以 go:noinline 或 go:unitptrescapes 开头;

  4. 必须有函数体;

// Inlining budget parameters, gathered in one place
const (
	// 解析 ast 的时候节点限制
	inlineMaxBudget       = 80
	inlineExtraAppendCost = 0
	// default is to inline if there's at most one call. -l=4 overrides this by using 1 instead.
	inlineExtraCallCost  = 57              // 57 was benchmarked to provided most benefit with no bad surprises; see https://github.com/golang/go/issues/19348#issuecomment-439370742
	inlineExtraPanicCost = 1               // do not penalize inlining panics.
	inlineExtraThrowCost = inlineMaxBudget // with current (2018-05/1.11) code, inlining runtime.throw does not help.

	inlineBigFunctionNodes   = 5000 // Functions with this many nodes are considered "big".
	inlineBigFunctionMaxCost = 20   // Max cost of inlinee when inlining into a "big" function.
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值