当前位置: 首页 > 知识库问答 >
问题:

RDSEED和RDRAND之间的性能差异可以忽略不计

容学林
2023-03-14

最近的Intel芯片(Ivy Bridge及以上)有生成(伪)随机位的指令<代码>RDSEED输出从芯片上传感器收集的熵生成的“真实”随机位RDRAND输出由真随机数生成器播种的伪随机数生成器生成的位。根据英特尔的文档,RDSEED速度较慢,因为收集熵的成本很高。因此,RDRAND作为一种更便宜的替代方案提供,其输出对于大多数加密应用程序来说是足够安全的。(这类似于Unix系统上的开发/随机(dev/random)与开发/urandom(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;
}
  • Intel Core i7-6700 CPU@3.40GHz
  • Ubuntu 16.04
  • gcc 5.4.0

共有3个答案

濮阳宏硕
2023-03-14

有趣-在我使用3.6 GHz 10核英特尔酷睿i9(在iMac上)的情况下,使用上述程序(更正为在失败的情况下重复RDRAND/RDSEED调用)我观察到:

$ ./rdseed-test 
RDRAND: 1751837
RDSEED: 1752472, 1.00

我必须承认,我很困惑——几天后尝试同样的可执行文件会让我产生3倍的差异,就像上面其他人报告的那样:

$ ./rdseed-test 
RDRAND: 1761312
RDSEED: 5309609, 3.01

不知道为什么有时候RDSEED的运行速度和RDRAND一样快,有时候慢三倍。

柴辰阳
2023-03-14

对我来说,在核心m7-6Y75上,测试程序中的RDSEED偶尔会失败(我添加了两个断言(ok) s,第二个偶尔会失败)。正确的代码将重试,导致性能差异有利于RDRAND。(RDRAND也需要重试,但在实践中似乎不会发生,因此RDRAND更快。)

孟俊晖
2023-03-14

您没有检查返回值,因此不知道生成了多少实际随机数。通过重试,正如Florian建议的那样,RDSEED版本的速度要慢3倍以上:

RDRAND: 1989817
RDSEED: 6636792, 3.34 

在这种情况下,硬件熵源可能只以有限的速率生成,这会导致以比熵再生更快的速率调用时失败<另一方面,code>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();
 类似资料:
  • 问题内容: 我正在计算稀疏自动编码器的算法。我已经使用和在python中实现了它。代码几乎相同,但是性能却大不相同。matlab完成任务所需的时间为0.252454秒,而numpy为0.973672151566,几乎是原来的四倍。在最小化问题中,我将在以后多次调用此代码,因此这种差异会导致实现之间的延迟几分钟。这是正常行为吗?如何提高numpy的性能? numpy实现: Sparse.rho是调整

  • 是的,这是一个老话题,但我还是有些困惑。 在爪哇,人们说: LinkedList的插入速度比ArrayList快。这里插入是什么意思?如果这意味着向后移动一些元素,然后将元素放在中间的空点,那么ArrayList应该比LinkedList慢。如果插入只意味着添加(对象)操作,这怎么会慢呢?

  • 我想计算文本语料库中单词的词频。我一直在使用NLTK的word_tokenize,后跟概率。FreqDist一段时间来完成这项工作。单词_tokenize返回一个列表,该列表由FreqDist转换为频率分布。然而,我最近在collections(collections.Counter)中遇到了计数器函数,它似乎在做完全相同的事情。FreqDist和Counter都有一个最常用(n)函数,返回n个最

  • 问题内容: 我想简化我的jQuery Backbone.js Web应用程序中的内容。一种简化就是我的菜单和对话框小部件的行为。 以前,我是在开始时创建菜单的div框并使用来隐藏它们的。当我需要菜单时,我更改了样式,然后使用jQuery ui位置工具定位div框(由于无法定位具有的元素),完成后,最终将其样式更改为。 现在,我想用隐藏它们,然后在需要时使用position实用工具,然后将样式更改为

  • 我想写一个矩阵逆的单元测试。 在某些地方,我有0.0f,而反向的单元格有-0.0f,它给出了一个错误,这些单元格不相等。 有没有办法忽略这个错误?

  • 是的,这是一个老话题,但我仍然有一些困惑。 在Java,人们说: > 如果我随机访问它的元素,ArrayList比LinkedList快。我认为随机存取意味着“给我第n个元素”。为什么ArrayList更快? LinkedList的删除速度比ArrayList快。我理解这一点。ArrayList速度较慢,因为需要重新分配内部备份阵列。代码说明: LinkedList的插入速度比ArrayList快