使用cpu的时钟周期作为随机数发生器的种子

skoo · · 4380 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

对于一个伪随机数发生器来说,种子的设置是非常重要的;Go语言runtime中的每个线程也有自己的一个随机数发生器,当然也是伪的,这个伪随机数发生器的种子设置采用了另外一种方法——使用了cpu的时钟周期计数器。

go语言的实现采用了一段汇编代码读取cpu的cycle信息,如下:

TEXT runtime·cputicks(SB),7,$0
	RDTSC
	SHLQ	$32, DX
	ADDQ	DX, AX
	RET

这段汇编代码的语法好像有点奇怪,和平时常见的AT&T语法有那么一点不同;确实,Go语言有一套自己的编译器,汇编器当然也是自己的了。这套编译器其实是Plan9平台上的玩意,个人觉得这汇编语法更顺眼一点,相比AT&T来说。

这里采用汇编实现的函数runtime·cputicks,第一条就是rdtsc指令。rdtsc指令就是核心,它是用来获取cpu自从加电以来执行的周期数,读取到的64位整数的低32位保存在AX寄存器,高32位保存到DX寄存器。所以,接下来的SHLQ指令就是将DX中的高32位值左移32位,然后通过ADD指令和低32位值加起来就得到了cpu的cycle值了。

可以看出使用cpu的时钟周期来作为随机发生器的种子是一种高精度的方法,比采用当前时间戳的精度要高很多。也有不少人采用rdtsc指令来做代码的性能测量,也就是在执行之前读取一下cpu cycle,完成后再读取一次,最后求一下差值。使用rdtsc做性能profiling在现在这些高端cpu上可能不那么靠谱了,主要是因为cpu支持指令乱序执行的原因,当然也还有一些其他的原因,可以看这篇文章:http://www.ccsl.carleton.ca/~jamuir/rdtscpm1.pdf

对了,rdtsc是read time stamp counter的缩写。

** 孤陋寡闻,第一次见这指令的使用,好久不写博客了,随手记录一下。多关注,留意细节可以学到蛮多意想不到的东西。


有疑问加站长微信联系(非本文作者)

本文来自:skoo's notes

感谢作者:skoo

查看原文:使用cpu的时钟周期作为随机数发生器的种子

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4380 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传