title: Negligible difference in performance between RDSEED and RDRAND
body: <p>Recent Intel chips (Ivy Bridge and up) have instructions for generating (pseudo) random bits. <code>RDSEED</code> outputs "true" random bits generated from entropy gathered from a sensor on the chip. <code>RDRAND</code> outputs bits generated from a pseudorandom number generator <em>seeded</em> by the true random number generator. According to <a href="https://software.intel.com/en-us/blogs/2012/11/17/the-difference-between-rdrand-and-rdseed" rel="nofollow noreferrer">Intel's documentation</a>, <code>RDSEED</code> is slower, since gathering entropy is costly. Thus, <code>RDRAND</code> is offered as a cheaper alternative, and its output is sufficiently secure for most cryptographic applications. (This is analogous to the <code>/dev/random</code> versus <code>/dev/urandom</code> on Unix systems.)</p>
  
  <p>I was curious about the performance difference between the two instructions, so I wrote some code to compare them. To my surprise, I find there is <strong>virtually no difference</strong> in performance. Could anyone provide an explanation? Code and system details follow.</p>
  
  <h2>Benchmark</h2>
  
  <pre><code>/* 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 &lt;time.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;x86intrin.h&gt;
  
  #define BUFSIZE (1&lt;&lt;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 &lt; BUFSIZE; i++) {
      ok  = _rdrand64_step(&amp;rand[i]);
    }
    bm = clock() - start;
    printf("RDRAND: %li\n", bm);
  
    // RDSEED
    start = clock();
    for (i = 0; i &lt; BUFSIZE; i++) {
      ok = _rdseed64_step(&amp;seed[i]);
    }
    end = clock();
    printf("RDSEED: %li, %.2lf\n", end - start, (double)(end-start)/bm);
  
    free(rand);
    free(seed);
    return 0;
  }
  </code></pre>
  
  <h2>System details</h2>
  
  <ul>
  <li>Intel Core i7-6700 CPU @ 3.40GHz</li>
  <li>Ubuntu 16.04</li>
  <li>gcc 5.4.0</li>
  </ul>