# Random Number Code Size

In an ideal world, a good random number generator ought not to require a lot of code code to implement or execute.

## A Simple Example

Let's consider this example of code that prints out eight random numbers.

```#include "pcg_random.hpp"
#include <cstdio>

int main()
{
pcg32 rng;

for (int i = 0; i < 8; ++i)
printf("%08x\n", rng());
}
```

And let's see how much code we'd produce with PCG and if we swapped pcg32 for a few other generators. (The code was compiled with GCC 4.8 using -O2 -fno-asynchronous-unwind-tables -fno-exceptions -fno-align-loops.)

Generator Init Instrs Init Bytes Loop Instrs Loop Bytes
PCG 64/32 (XSH-RR) 4 35 15 52
Minstd (LCG) 3 16 17 61
XorShift* 64/32 3 25 17 60
Ran 6 55 33 115
MT 19937 51 197 49 174

We can see here that the PCG family is comparable in code size to other generators known for their compact code, and actually has fewer instructions inside the loop. The Mersenne Twister and Ran (from Numerical Recipes) are much worse for code size—their implementations are much more complex, and it shows in the generated code (the same also applies arc4random).

### The Actual Code

FWIW, here's the code that was generated by GCC for the above code:

```_main:
## Function prologue:
pushq   %r13
pushq   %r12
pushq   %rbp
pushq   %rbx
subq    \$8, %rsp
## Initialize RNG and loop constants
movabsq \$5573589319906701683, %rcx
movl    \$8, %ebp
movabsq \$6364136223846793005, %r13
movabsq \$1442695040888963407, %r12
.align 4
## Loop
L2:
movq    %rcx, %rbx
movq    %rcx, %rsi
xorl    %eax, %eax
imulq   %r13, %rbx
shrq    \$18, %rsi
leaq    LC0(%rip), %rdi   ## string "%08x\n"
xorq    %rcx, %rsi
shrq    \$59, %rcx
shrq    \$27, %rsi
rorl   %cl, %esi
call    _printf
movq    %rbx, %rcx
subl    \$1, %ebp
jne     L2
## Function Epilogue
xorl    %eax, %eax
popq    %rbx
popq    %rbp
popq    %r12
popq    %r13
ret
```

Interestingly, Clang produces quite different code:

```_main:
## Function prologue:
pushq   %rbp
movq    %rsp, %rbp
pushq   %rbx
pushq   %rax
leaq    L_.str(%rip), %rbx   ## string "%08x\n"
## Directly print out eight numbers
movl    \$676697322, %esi
xorl    %eax, %eax
movq    %rbx, %rdi
callq   _printf
movl    \$420258633, %esi
xorl    %eax, %eax
movq    %rbx, %rdi
callq   _printf
movl    \$-876335118, %esi
xorl    %eax, %eax
movq    %rbx, %rdi
callq   _printf
movl    \$-699367085, %esi
xorl    %eax, %eax
movq    %rbx, %rdi
callq   _printf
movl    \$-1029176017, %esi
xorl    %eax, %eax
movq    %rbx, %rdi
callq   _printf
movl    \$257272927, %esi
xorl    %eax, %eax
movq    %rbx, %rdi
callq   _printf
movl    \$-687915470, %esi
xorl    %eax, %eax
movq    %rbx, %rdi
callq   _printf
movl    \$1330014364, %esi
xorl    %eax, %eax
movq    %rbx, %rdi
callq   _printf
xorl    %eax, %eax
## Function Epilogue