英文:
Is math.bits in Go using machine code instructions?
问题
这些新的golang包"math/bits"提供了一些有用的函数。源代码展示了这些函数结果是如何计算的。
当处理器支持时,这些函数是否会被相应的处理器OP代码所替代?
英文:
The new golang package "math/bits" provides useful functions. The source code shows how the function result are computed.
Are these functions replaced by the corresponding processor OP codes when available?
答案1
得分: 3
是的,正如在Go 1.9发布说明:新的位操作包中所述:
Go 1.9包含一个新的包
math/bits
,其中包含用于操作位的优化实现。在大多数架构上,该包中的函数还被编译器识别并作为内部函数处理,以提供额外的性能。
一些相关的/历史性的GitHub问题:
proposal: cmd/compile: 将用户定义的汇编函数转换为内部函数 #17373
英文:
Yes, as stated in Go 1.9 Release Notes: New bit manipulation package:
> Go 1.9 includes a new package, math/bits
, with optimized implementations for manipulating bits. On most architectures, functions in this package are additionally recognized by the compiler and treated as intrinsics for additional performance.
Some related / historical github issues:
math/bits: an integer bit twiddling library #18616
proposal: cmd/compile: intrinsicify user defined assembly functions #17373
Provide a builtin for population counting / hamming distance #10757
答案2
得分: 3
是的,可以。你可以在这里看到它的工作示例:
首先编译以下代码:
package main
import (
"fmt"
"math/bits"
)
func count(i uint) {
fmt.Printf("%d has %d length\n", i, bits.Len(i))
}
func main() {
for i := uint(0); i < 100; i++ {
count(i)
}
}
然后查看反汇编代码。注意BSR指令 - 位扫描反转,根据手册的说明:在寄存器或内存位置(第二个操作数)中搜索最高有效位。
0000000000489620 <main.count>:
489620: 64 48 8b 0c 25 f8 ff mov %fs:0xfffffffffffffff8,%rcx
489627: ff ff
489629: 48 3b 61 10 cmp 0x10(%rcx),%rsp
48962d: 0f 86 f2 00 00 00 jbe 489725 <main.count+0x105>
489633: 48 83 ec 78 sub $0x78,%rsp
489637: 48 89 6c 24 70 mov %rbp,0x70(%rsp)
48963c: 48 8d 6c 24 70 lea 0x70(%rsp),%rbp
489641: 48 8b 84 24 80 00 00 mov 0x80(%rsp),%rax
489648: 00
489649: 48 0f bd c8 bsr %rax,%rcx ; **** 位扫描反转指令 ****
48964d: 48 89 44 24 48 mov %rax,0x48(%rsp)
489652: 48 c7 c0 ff ff ff ff mov $0xffffffffffffffff,%rax
489659: 48 0f 44 c8 cmove %rax,%rcx
48965d: 48 8d 41 01 lea 0x1(%rcx),%rax
英文:
Yes it does. You can see an example of it working here
first compile this
package main
import (
"fmt"
"math/bits"
)
func count(i uint) {
fmt.Printf("%d has %d length\n", i, bits.Len(i))
}
func main() {
for i := uint(0); i < 100; i++ {
count(i)
}
}
Then look at the disassembly. Note the BSR instruction - Bit Scan Reverse which from the manual: Searches the value in a register or a memory location (second operand) for the most-significant set bit.
0000000000489620 <main.count>:
489620: 64 48 8b 0c 25 f8 ff mov %fs:0xfffffffffffffff8,%rcx
489627: ff ff
489629: 48 3b 61 10 cmp 0x10(%rcx),%rsp
48962d: 0f 86 f2 00 00 00 jbe 489725 <main.count+0x105>
489633: 48 83 ec 78 sub $0x78,%rsp
489637: 48 89 6c 24 70 mov %rbp,0x70(%rsp)
48963c: 48 8d 6c 24 70 lea 0x70(%rsp),%rbp
489641: 48 8b 84 24 80 00 00 mov 0x80(%rsp),%rax
489648: 00
489649: 48 0f bd c8 bsr %rax,%rcx ; **** Bit scan reverse instruction ***
48964d: 48 89 44 24 48 mov %rax,0x48(%rsp)
489652: 48 c7 c0 ff ff ff ff mov $0xffffffffffffffff,%rax
489659: 48 0f 44 c8 cmove %rax,%rcx
48965d: 48 8d 41 01 lea 0x1(%rcx),%rax
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论