Performance go中ASM函数调用的开销

Performance go中ASM函数调用的开销,performance,optimization,assembly,go,Performance,Optimization,Assembly,Go,我目前正在玩围棋,它是汇编,浮点运算的性能(float32)和纳秒级的优化。我被一个简单函数调用的开销搞糊涂了: func BenchmarkEmpty(b *testing.B) { for i := 0; i < b.N; i++ { } } func BenchmarkNop(b *testing.B) { for i := 0; i < b.N; i++ { doNop() } } 结果(go test-bench.): 我不

我目前正在玩围棋,它是汇编,浮点运算的性能(
float32
)和纳秒级的优化。我被一个简单函数调用的开销搞糊涂了:

func BenchmarkEmpty(b *testing.B) {
    for i := 0; i < b.N; i++ {
    }
}
func BenchmarkNop(b *testing.B) {
    for i := 0; i < b.N; i++ {
        doNop()
    }
}
结果(
go test-bench.
):

我不习惯组装和/或go的内部构件。go编译器/链接器是否可以内联汇编中定义的函数?我能给链接器一个提示吗?对于一些简单的函数,如“添加两个R3向量”,这会消耗掉所有可能的性能增益


(go 1.4.2,amd64)

装配功能不是内联的。以下是你可以尝试的三件事:

  • 将循环移动到集合中。例如,使用此功能:

    func Sum(xs []int64) int64
    
    您可以这样做:

    #include "textflag.h"
    
    TEXT ·Sum(SB),NOSPLIT,$0-24
        MOVQ  xs+0(FP),DI
        MOVQ  xs+8(FP),SI
        MOVQ  $0,CX
        MOVQ  $0,AX
    
    L1: CMPQ  AX,SI           // i < len(xs)
        JGE   Z1
        LEAQ  (DI)(AX*8),BX   // BX = &xs[i]
        MOVQ  (BX),BX         // BX = *BX
        ADDQ  BX,CX           // CX += BX
        INCQ  AX              // i++
        JMP   L1
    
    Z1: MOVQ  CX,ret+24(FP)
        RET
    


  • 您确定Go不仅仅是优化BenchmarkEmpty()中的循环吗?如果是这样的话,将BenchmarkEmpty与BenchmarkNop进行比较就不是什么比较了。我已经查看了分解,循环仍然存在。顺便说一句,doNop(
    func doNopGeneric(){}
    )的通用实现已经过优化。我希望在ASM中内联一些基本函数,并且仍然在go中构建我的算法。但否定的答案仍然是答案;)
    func Sum(xs []int64) int64
    
    #include "textflag.h"
    
    TEXT ·Sum(SB),NOSPLIT,$0-24
        MOVQ  xs+0(FP),DI
        MOVQ  xs+8(FP),SI
        MOVQ  $0,CX
        MOVQ  $0,AX
    
    L1: CMPQ  AX,SI           // i < len(xs)
        JGE   Z1
        LEAQ  (DI)(AX*8),BX   // BX = &xs[i]
        MOVQ  (BX),BX         // BX = *BX
        ADDQ  BX,CX           // CX += BX
        INCQ  AX              // i++
        JMP   L1
    
    Z1: MOVQ  CX,ret+24(FP)
        RET
    
    //extern open
    func c_open(name *byte, mode int, perm int) int