如何在Go中使用cputicks函数,如何使用Go的runtime中的cputicks函数?
在C中,可以利用C嵌汇编的方式,通过rdtsc寄存器获取CPU的ticks。在Go中一种方式是可以通过Plan 9汇编定义一个Go的函数:
-
Groovy 代码
1 | TEXT ·cputicks(SB),NOSPLIT,$ 0 - 0 |
另一种方式,则是直接调用Go的私有函数runtime.cputicks。具体代码如下所示:
-
Groovy 代码
在这个例子中,使用了//go:linkname 这个编译制导语句,它会在链接时,把package main下面的cputicks与runtime.cputicks绑定在一起。这样在调用cputicks时,其实是调用的runtime.cputicks。另外,如果是只有这一个Go文件时,请在当前目录下创建一个空的asm.s文件。这是为了欺骗编译器。在编译期,当Go的编译器发现func cputicks() int64这个函数声明时,会寻找该函数的函数体。如果当前只有一个Go文件,则编译器就可以判定这个函数是没有函数体的。这样到不了链接期,编译过程就被打断了。如果在旁边再有一个空的asm.s文件,则在编译这个Go文件时,Go的编译器无法判断是否真的不存在这个函数声明的函数体。也就在不会在编译期出错了。当进入链接期,由于linkname的作用,该函数可以编译通过。
另外,不仅是cputicks,对于任何的不可见的函数都可以这么做。不过不建议滥用,请控制这种用法的使用范围
Go程序的链接并不使用链接脚本,如何给Go程序增加自定义段?
Go使用自带的链接器go tool link。这个链接器不使用链接脚本,所以在Go中无法想C那样定义自定义段。但并不是说在Go中没法增加自定义段。可以借助CGO实现这个目的。下面是Go文件
-
Groovy 代码
只需要在这里面能引起C的编译即可。编译命令是关键:
-
Bash 代码
1 | go build -o main -ldflags "-extldflags '-Xlinker -T linux64.lds'" |
这里借助gcc的把链接脚本里面的信息拿进来。最后效果:
-
Bash 代码
查看代码
1 | 0000700100000001 <__CustomSeg>: |
2 | 700100000001: 00 00 add %al,(%rax) |
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)