为了账号安全,请及时绑定邮箱和手机立即绑定

编译与手写程序集的性能差异

编译与手写程序集的性能差异

Go
慕无忌1623718 2021-08-10 17:15:09
我一直在尝试在 Go 中使用汇编语言,并编写了一个汉明权函数作为练习。我已经在这个 SO 答案上建立了一个本地 Go 版本,程序集版本基于来自 AMD (page 180) 的这个文档。在对这两个函数进行基准测试后,我发现原生 Go 版本比汇编版本快 1.5 到 2 倍,尽管手写汇编版本几乎与go tool 6g -S popcount.go.输出 go test -bench=.PASSBenchmarkPopCount       100000000               19.4 ns/op BenchmarkPopCount_g     200000000                8.97 ns/opok      popcount   4.777spopcount.gopackage popcountfunc popCount(i uint32) uint32 // Defined in popcount_amd64.sfunc popCount_g(i uint32) uint32 {    i = i - ((i >> 1) & 0x55555555)    i = (i & 0x33333333) + ((i >> 2) & 0x33333333)    return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24}popcount_test.gopackage popcountimport "testing"func TestPopcount(t *testing.T) {    for i := uint32(0); i < uint32(100); i++ {        if popCount(i) != popCount_g(i) {            t.Fatalf("failed on input = %v", i)        }    }}func BenchmarkPopCount(b *testing.B) {    for i := 0; i < b.N; i++ {        popCount(uint32(i))    }}func BenchmarkPopCount_g(b *testing.B) {    for i := 0; i < b.N; i++ {        popCount_g(uint32(i))    }}popcount_amd64.s// func popCount(i uint32) uint32TEXT ·popCount(SB),$0    MOVL i+0(FP), BP        // i    MOVL BP, BX             // i    SHRL $1, BX             // i >> 1    ANDL $0x055555555, BX   // (i >> 1) & 0x55555555    SUBL BX, BP             // w = i - ((i >> 1) & 0x55555555)    MOVL BP, AX             // w    SHRL $2, BP             // w >> 2    ANDL $0x033333333, AX   // w & 0x33333333    ANDL $0x033333333, BP   // (w >> 2) & 0x33333333输出 go tool 6g -S popcount.go我从这里知道这些FUNCDATA行包含垃圾收集器的信息,但除此之外我没有看到任何明显的差异。什么可能导致这两个功能之间的速度差异如此大?
查看完整描述

1 回答

  • 1 回答
  • 0 关注
  • 179 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信