简体   繁体   English

go中的ASM函数调用的开销

[英]Overhead of ASM-function-call in go

I currently play around with go, it's assembly, performance of floating point operations ( float32 ) and optimizations in the nano-seconds-scale. 我目前正在研究go,它的组装,浮点运算的性能( float32 )以及纳秒级的优化。 I was a bit confused by the overhead of a simple function call: 一个简单的函数调用的开销让我有些困惑:

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()
    }
}

The implementation of doNop: doNop的实现:

TEXT ·doNop(SB),0,$0-0
    RET

The result ( go test -bench . ): 结果( go test -bench . ):

BenchmarkEmpty        2000000000               0.30 ns/op
BenchmarkNop  2000000000               1.73 ns/op

Im not used to assembly and/ or the internals of go. 我不习惯组装和/或围棋内部。 It is possible fo the go compiler/ linker to inline a function defined in assembly? go编译器/链接器是否可以内联汇编中定义的函数? Can I give the linker a hint somehow? 我可以以某种方式给链接器提示吗? For some simple functions like 'add two R3-vectors' this eats up all possible performance gain. 对于一些简单的功能,例如“相加两个R3向量”,这会耗尽所有可能的性能增益。

(go 1.4.2, amd64) (执行1.4.2,amd64)

Assembly functions are not inlined. 汇编函数未内联。 Here are 3 things you could try: 您可以尝试以下3种方法:

  1. Move your loop into assembly. 将循环移动到汇编中。 For example with this function: 例如具有以下功能:

     func Sum(xs []int64) int64 

    You can do this: 你可以这样做:

     #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 

    If you look in the standard libraries you will see examples of this. 如果您查看标准库,则会看到此示例。

  2. Write some of your code in c, leverage the support it has for intrinsics or inline assembly, and use cgo to call it from go. 用c编写一些代码,利用其对内在函数或内联汇编的支持,并使用cgo从头开始进行调用。

  3. Use gccgo to do the same thing as #2, except you can do it directly: 使用gccgo可以执行与#2相同的操作,但是可以直接执行以下操作:

     //extern open func c_open(name *byte, mode int, perm int) int 

    https://golang.org/doc/install/gccgo#Function_names https://golang.org/doc/install/gccgo#Function_names

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM