我已经看到英特尔似乎已经包含了一个新的汇编函数来获取从硬件获得的真实随机数.该指令的名称是RdRand,但在互联网上只能看到少量细节:http://en.wikipedia.org/wiki/RdRand
关于这条新指令及其在C++ 11中的使用我的问题如下:
生成的随机数是否RdRand真的随机?(每个位是由不相关的白噪声或量子过程产生的?)
它是Ivy Bridge处理器的一个特殊功能,英特尔是否会继续在下一代CPU中实现此功能?
如何通过C++ 11使用它?也许有,std::random_device但RdRand如果指令可用,编译器是否已经调用?
如何RdRand在编译程序时检查是否真的被调用?
在查看英特尔数字随机数发生器(DRNG)软件实施指南之后,我对RDRAND调用时生成器的内部状态会发生什么问题提出了一些问题.不幸的是,答案似乎不在指南中.
根据该指南,在DRNG内部有四个128位缓冲器,用于提供随机位以RDRAND进行漏极.RDRAND本身将提供16位,32位或64位随机数据,具体取决于目标寄存器的宽度:
rdrand ax ; put 16 random bits in ax
rdrand eax ; put 32 random bits in eax
rdrand rax ; put 64 random bits in rax
Run Code Online (Sandbox Code Playgroud)
使用更大的目标寄存器会更快地清空这些128位缓冲区吗?例如,如果我只需要2位随机性,那么我是否应该经历在64位寄存器上使用16位寄存器的麻烦?这会对DRNG的吞吐量产生任何影响吗?我想避免消耗比必要更多的随机性.
指南说执行后将设置进位标志RDRAND:
CF = 1 Destination register valid. Non-zero random value
available at time of execution. Result placed in register.
CF = 0 Destination register all zeros. Random value not available
at time of execution. May be retried.
Run Code Online (Sandbox Code Playgroud)
"不可用"是什么意思?随机数据是否可用,因为RDRAND调用过快地耗尽了这些128位缓冲区?或者不可用意味着DRNG未通过健康检查而无法生成任何新数据?基本上,我试图理解CF …
今天我想:好吧,即使RDRAND对NIST SP 800-90A的实施有很大的怀疑,它仍然是伪随机数发生器(PRNG)的硬件实现,对于非敏感应用来说必须足够好.所以我想在我的游戏而不是Mersenne Twister上使用它.
因此,为了查看使用该指令是否有任何性能提升,我比较了以下两个代码的时间:
// test.cpp
#include <cstdio>
int main()
{
unsigned int rnd = 0;
for(int i = 0; i < 10000000; ++i) {
__builtin_ia32_rdrand32_step(&rnd);
}
printf("%x\n", rnd);
}
Run Code Online (Sandbox Code Playgroud)
和
//test2.cpp
#include <cstdio>
#include <random>
int main()
{
unsigned int rnd = 0;
__builtin_ia32_rdrand32_step(&rnd);
std::mt19937 gen(rnd);
for(int i = 0; i < 10000000; ++i) {
rnd ^= gen();
}
printf("%x\n", rnd);
}
Run Code Online (Sandbox Code Playgroud)
通过运行这两个我得到:
$ time ./test
d230449a
real 0m0.361s
user 0m0.358s
sys 0m0.002s
$ time ./test2
bfc4e472 …Run Code Online (Sandbox Code Playgroud) 我需要从处理器(英特尔酷睿i3)中的英特尔随机发生器获取随机数.我不想使用任何库.我想在C++中使用汇编器粘贴,但我不知道哪些寄存器和指令应该使用.
我希望从C#程序集中使用英特尔的数字随机数生成器(Ivy Bridge中的RDRAND指令).我看过cpp libs,但我希望有一个更"管理"的解决方案.有任何想法吗?
较新的英特尔处理器包括一个DRBG,它可以生成随机数,您可以使用RDRAND指令读取这些数字.它涉及从硬件熵源产生的256位种子S,其取决于亚稳振荡器中的噪声.用于得到数字的算法是有效的AES(K,V),其中K是从S的一半导出的短暂密钥,V是从S的另一半导出的IV.无论如何,我认为; 一些审计过的人更好地解释了这一点.
出于各种原因,我想以编程方式原位审计此机制的性能,这需要能够读取或导出两件事:
在多次迭代中使用此输出和RDRAND输出将为我提供所需的测试数据以进行此确定.
但是,在软件开发人员手册或其他地方,我找不到任何记录完成这些任务的方法.
假设我愿意编写一个Linux内核模块来实现这一点,并且我愿意使用RDMSR或任何其他可用方法,包括调用片上设备(如MEI),是否可以获取这些数据?
是否有任何现成的库,以便numpy程序可以使用intel硬件prng(rdrand)来填充随机数的缓冲区?
如果失败了,有人会指出我正确的方向,我可以适应或使用一些C代码(我使用CPython和Cython与numpy,所以最小的包装器就足够了).
我想要的随机生成器是[0,1]之间的均匀随机数.
我在看 HJ Lu 的PATCH: Update x86 rdrand internals。我不知道是否应该使用_rdrand_u64, _rdrand64_step,或者是否还有其他功能。似乎没有为他们编写的测试用例。
似乎也缺少手册页(来自 Ubuntu 14、GCC 4.8.4):
$ man -k rdrand
rdrand: nothing appropriate.
Run Code Online (Sandbox Code Playgroud)
如何使用RDRAND内在函数生成一个 32 字节的块?
一个相关的问题是RDRAND 和 RDSEED 内在函数 GCC 和 Intel C++。但它没有告诉我如何使用它们,或者如何生成一个块。
我在网上搜索了很长一段时间,却找不到明确的答案.我想知道intel的rdrand指令生成的随机数的质量.例如,它与IDQ的卡相比如何?它真的是随机的还是伪随机的?
谢谢