问题
Go tip 将以下代码编译成以下汇编:
func fff(s string) int {
return strings.IndexByte(s, ' ')
}
EXT fff(SB)
func fff(s string) int{
0x50f06064488b0c25f8ffffff MOVQFS:0xfffffff8,CX
0x50f069483b6110 CMPQ 0x10(CX),SP
0x50f06d763f JBE0x50f0ae
0x50f06f4883ec28 SUBQ $0x28,SP
0x50f07348896c2420 MOVQBP,0x20(SP)
0x50f078488d6c2420 LEAQ 0x20(SP),BP
return strings.IndexByte(s,' ')
0x50f07d488b442430 MOVQ0x30(SP),AX
0x50f08248890424MOVQAX,0(SP)
0x50f086488b442438 MOVQ0x38(SP),AX
0x50f08b4889442408MOVQAX,0x8(SP)
0x50f090c644241020 MOVB $0x20,0x10(SP)
0x50f095e8b635efff CALLstrings.IndexByte(SB)
0x50f09a488b442418 MOVQ0x18(SP),AX
0x50f09f4889442440MOVQAX,0x40(SP)
0x50f0a4488b6c2420 MOVQ0x20(SP),BP
0x50f0a94883c428 ADDQ $0x28,SP
0x50f0adc3 RET
func fff(s string) int{
0x50f0aee85d7df4ff CALLruntime.morestack_noctxt(SB)
0x50f0b3ebab JMPfff(SB)
汇编使用以下指令从 fff
复制顺序栈参数到 IndexByte
:
0x50f07d488b442430 MOVQ0x30(SP),AX
0x50f08248890424MOVQAX,0(SP)
0x50f086488b442438 MOVQ0x38(SP),AX
0x50f08b4889442408MOVQAX,0x8(SP)
这些指令可能被较短(且可能更快)的汇编替代:
MOVO 0x30(SP),Xn
MOVO Xn,0(SP)
解决方案
添加相应的针对特定架构的重写规则,将顺序内存移动合并到更大的内存移动中。
cc'ing @randall77 和 @TocarIP 。
3条答案
按热度按时间juzqafwq1#
We've tried this in https://go-review.googlesource.com/c/go/+/57130 but it caused performance regression #23424 and had to be reverted
ekqde3dh2#
@TocarIP ,可能 the CL 必须仅限于由 @ulikunitz 在 #23424(评论)中指出的对齐加载/存储对?
现在我们可以通过将 CL 与该问题中的基准测试进行比较来避免 #23424 的回归。
vx6bjr1n3#
/cc @josharian@mdempsky