我目前正在玩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()
}
}
doNop的实现:
TEXT ·doNop(SB),0,$0-0
RET
结果(go test -bench .
):
BenchmarkEmpty 2000000000 0.30 ns/op
BenchmarkNop 2000000000 1.73 ns/op
我不习惯组装和/或go的内部。 go编译器/链接器可以内联在程序集中定义的函数吗?我能以某种方式给链接器一个提示吗?对于一些简单的函数,例如&#39;添加两个R3-向量&#39;这会降低所有可能的性能提升。
(去1.4.2,amd64)
答案 0 :(得分:0)
汇编函数未内联。以下是您可以尝试的三件事:
将循环移动到装配体中。例如,使用此功能:
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
如果您查看标准库,您将看到此示例。
在c中编写一些代码,利用它对内在函数或内联汇编的支持,并使用cgo从go调用它。
使用gccgo执行与#2相同的操作,但您可以直接执行此操作:
//extern open
func c_open(name *byte, mode int, perm int) int