首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >RDSEED与RDRAND的性能差异可以忽略不计

RDSEED与RDRAND的性能差异可以忽略不计
EN

Stack Overflow用户
提问于 2017-07-26 19:56:09
回答 3查看 1.1K关注 0票数 4

最近的英特尔芯片(常春藤桥和向上)有指令产生(伪随机)比特。RDSEED输出从芯片上传感器收集到的熵产生的“真”随机比特。RDRAND输出由真实随机数生成器所播种的伪随机数生成器产生的比特。根据英特尔的文件的说法,RDSEED速度较慢,因为收集熵的代价很高。因此,RDRAND作为一种更便宜的替代方案提供,它的输出对于大多数密码应用程序来说都是足够安全的。(这类似于Unix系统上的/dev/random/dev/urandom。)

我很好奇这两个指令之间的性能差异,所以我编写了一些代码来比较它们。令我惊讶的是,我发现实际上在性能上并没有不同的。有人能解释一下吗?代码和系统详细信息如下。

基准测试

代码语言:javascript
运行
复制
/* 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;
}

系统细节

  • Intel Core i7-6700 CPU @ 3.40GHz
  • Ubuntu 16.04
  • gcc 5.4.0
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-26 20:28:13

您没有检查返回值,因此不检查生成了多少实际随机数。通过重试,作为建议RDSEED版本要慢3倍以上:

代码语言:javascript
运行
复制
RDRAND: 1989817
RDSEED: 6636792, 3.34 

在本文的掩护下,硬件熵源可能只产生有限的速率,当调用速度超过熵的再生速度时,这将导致RDSEED失败。另一方面,RDRAND只产生基于周期重播的伪随机序列,因此不太可能失败。

以下是修改后的代码摘录:

代码语言:javascript
运行
复制
  // 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();
票数 6
EN

Stack Overflow用户

发布于 2017-07-26 20:02:19

对我来说,在CoreM7-6Y75上,测试程序中的RDSEED偶尔会失败(我添加了两个assert (ok);,第二个偶尔失败)。正确的代码会重试,从而导致性能上的差异,从而有利于RDRAND。( RDRAND也需要重试,但在实践中似乎没有发生这种情况,因此RDRAND更快。)

票数 4
EN

Stack Overflow用户

发布于 2021-11-09 15:29:33

有趣的是,在我使用3.6 GHz 10-Core Intel Core i9 (on iMac)的例子中,我注意到上面的程序(在失败时重复RDRAND/RDSEED调用):

代码语言:javascript
运行
复制
$ ./rdseed-test 
RDRAND: 1751837
RDSEED: 1752472, 1.00

更新

我必须承认,我很困惑--几天后尝试这个相同的可执行文件给了我3x的差异,就像上面其他人报告的那样:

代码语言:javascript
运行
复制
$ ./rdseed-test 
RDRAND: 1761312
RDSEED: 5309609, 3.01

不知道为什么有时RDSEED跑得和RDRAND一样快,有时甚至比RDRAND慢三倍。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45336283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档