twe*_*ksp 4 random gcc cryptography x86-64
最近的英特尔芯片(Ivy Bridge及其上)具有生成(伪)随机位的指令.RDSEED输出从芯片上的传感器收集的熵产生的"真实"随机位.RDRAND输出由真随机数发生器播种的伪随机数发生器产生的比特.根据英特尔的文档,RDSEED速度较慢,因为收集熵是昂贵的.因此,RDRAND作为更便宜的替代方案提供,并且其输出对于大多数加密应用来说足够安全.(这类似于Unix系统上的/dev/random对比/dev/urandom.)
我很好奇两个指令之间的性能差异,所以我写了一些代码来比较它们.令我惊讶的是,我发现性能几乎没有差异.任何人都可以提供解释吗?代码和系统详细信息如下.
/* Compare the performance of RDSEED and RDRAND.
*
* Compute the CPU time used to fill a buffer with (pseudo) random bits
* using each instruction.
*
* Compile with: gcc -mdrnd -mdseed
*/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <x86intrin.h>
#define BUFSIZE (1<<24)
int main() {
unsigned int ok, i;
unsigned long long *rand = malloc(BUFSIZE*sizeof(unsigned long long)),
*seed = malloc(BUFSIZE*sizeof(unsigned long long));
clock_t start, end, bm;
// RDRAND (the benchmark)
start = clock();
for (i = 0; i < BUFSIZE; i++) {
ok = _rdrand64_step(&rand[i]);
}
bm = clock() - start;
printf("RDRAND: %li\n", bm);
// RDSEED
start = clock();
for (i = 0; i < BUFSIZE; i++) {
ok = _rdseed64_step(&seed[i]);
}
end = clock();
printf("RDSEED: %li, %.2lf\n", end - start, (double)(end-start)/bm);
free(rand);
free(seed);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您没有检查返回值,因此您不会生成多少实际随机数.随着重试,为弗洛里安建议的RDSEED版本是比较慢的3倍以上:
RDRAND: 1989817
RDSEED: 6636792, 3.34
Run Code Online (Sandbox Code Playgroud)
在封面下,硬件熵源可能仅以有限的速率生成,并且RDSEED当以比熵可以再生的速率更快的速率调用时,这导致失败.RDRAND另一方面,仅基于周期性重新种子生成伪随机序列,因此不太可能失败.
以下是修改后的代码摘录:
// RDRAND (the benchmark)
start = clock();
for (i = 0; i < BUFSIZE; i++) {
while (!_rdrand64_step(&rand[i]))
;
}
bm = clock() - start;
printf("RDRAND: %li\n", bm);
// RDSEED
start = clock();
for (i = 0; i < BUFSIZE; i++) {
while (!_rdseed64_step(&seed[i]))
;
}
end = clock();
Run Code Online (Sandbox Code Playgroud)