【问题标题】:RDTSC on Intel Celeron 64-bit Assembly program英特尔赛扬 64 位汇编程序上的 RDTSC
【发布时间】:2015-02-08 22:09:04
【问题描述】:

我写了一个小的随机数字程序,它利用 RDTSC 给我随机性。我使用 FASM 在 Linux Mint 17 上编写了它。

问题是,它在 AMD FX 64 位 PC 上完美运行,但在 Windows 8 和 Linux Mint 下,英特尔赛扬上网本(64 位)上的确切代码失败(或挂起)(我双启动,所以我为 Win 8 修改了代码)

这可能是什么问题?这基本上是代码;

again:
rdtsc
and eax,1111b
cmp eax,10
jae again
;things to do with the random digit

我调试了一下,发现罪魁祸首隐藏在这部分代码中。但我也看不出有什么问题。它在我的 AMD PC 上完美运行。英特尔 CPU 是否默认禁用 RDTSC?

【问题讨论】:

  • Err... 我强烈建议不要使用 rdtsc 来获得随机性。它的一个问题是,如果在循环中调用,这样的函数将给出某个步长值的连续倍数加上一个偏移量(即,如果每次循环迭代需要 4 个总线周期,您可能会得到 1、5、9、13 ,1,5,9,13,...)。仅获取奇数或仅偶数值,或仅交替奇数/偶数值根本不是很随机。
  • 感谢您的回答。但我认为一位数不会有问题。 EAX/RAX 的回报对于一个随机的单个数字来说已经足够好了。无论如何只是一个简单的程序:D
  • 你会感到惊讶。如果你想要一些简单而实用的东西,我觉得最适合你的是linear-congruential generator。一个简单的例子:x_new = 1103515245*x_old + 12345;

标签: linux assembly fasm rdtsc


【解决方案1】:

您实际上是在读取时钟周期数(每秒数十亿次),然后不退出循环,除非它的最后 4 位

如果指令被禁用,您的程序将被操作系统杀死并出现“非法指令”错误。

【讨论】:

  • 可能发生的情况是,例如,如果循环占用 16 个总线周期的倍数并且第一次看到的值为 10 <= x <= 15Per comment above,例如,你会得到 13,13,13,13,13,13,13,... 没有尽头。
  • James,我的 AMD 机器没有这个问题。对于单个数字(例如从 0 到 9),它的随机性很好。但是对于我的赛扬上网本,您可能是对的,尽管我对此表示怀疑,因为两个 CPU 都是 64 位的。
  • @royalfinest 真的是时间问题。无法像上面所说的那样保证您的退出条件永远都会发生。
  • @royalfinest 你可以试试 rdtscp 指令,但这不太可能是英特尔的问题,我敢肯定他们现在已经注意到了
  • @royalfinest:RDTSC 不再测量 CPU 周期,只测量不受电源管理、涡轮增压等影响的标准化时钟上的周期。随之而来的是变化CPU 使用较慢的归一化时钟(例如,可能是 CPU 时钟速度的 1/16)并执行相当于 TSC += 16; 的操作,无论您做什么,您的循环都永远不会退出。一个简单的解决方法是在AND 之前使用eax = eax ^ (eax >> 16); 之类的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 1970-01-01
  • 2012-05-29
  • 2011-02-14
相关资源
最近更新 更多