go cmd/compile: merge sequential memory moves into bigger memory moves

ih99xse1  于 3个月前  发布在  Go
关注(0)|答案(3)|浏览(26)

问题

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 。

juzqafwq

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

ekqde3dh

ekqde3dh2#

@TocarIP ,可能 the CL 必须仅限于由 @ulikunitz 在 #23424(评论)中指出的对齐加载/存储对?
现在我们可以通过将 CL 与该问题中的基准测试进行比较来避免 #23424 的回归。

vx6bjr1n

vx6bjr1n3#

/cc @josharian@mdempsky

相关问题