// File: mburhanpurkar[P]fast_xorshift_plus/example.cpp
// Function: time_mt19937(float*, int, int, int, int)
static void time_mt19937(float *out, int niter, int ny, int nx, int stride)
{
    random_device rd;
    mt19937 rng(rd());
    uniform_real_distribution<> dist(1.0);

    // Start timing
    struct timeval tv0 = rng_helpers::get_time();
    
    for (int iter = 0; iter < niter; iter++)
        for (int ifreq = 0; ifreq < ny; ifreq++)
	    for (int it = 0; it < nx; it++)
	        out[ifreq*stride + it] = dist(rng);

    // Stop timing
    struct timeval tv1 = rng_helpers::get_time();
    double dt = rng_helpers::time_diff(tv0, tv1);
    double noutputs = double(niter) * double(ny) * double(nx);
    double ns_per_output = 1.0e9 * dt / noutputs;

    cout << "time_mt19937: ns_per_output = " << ns_per_output << endl;
}

// Assembly:
subq $0x27e8, %rsp           # imm = 0x27E8
movq %rdi, 0x27e0(%rsp)
movl %esi, 0x27dc(%rsp)
movl %edx, 0x27d8(%rsp)
movl %ecx, 0x27d4(%rsp)
movl %r8d, 0x27d0(%rsp)
leaq 0x1448(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x2b40
movq 0x48(%rsp), %rdi
callq 0x2be0
movl %eax, 0x54(%rsp)
jmp 0x247e
movl 0x54(%rsp), %eax
movl %eax, %eax
movl %eax, %esi
leaq 0xc0(%rsp), %rdi
callq 0x2bf0
jmp 0x2495
leaq 0xa0(%rsp), %rdi
vmovsd 0x2b63(%rip), %xmm1     # 0x5008
vmovaps %xmm1, %xmm0
callq 0x2c20
jmp 0x24b0
callq 0x2c50
movq %rdx, 0x38(%rsp)
movq %rax, 0x40(%rsp)
jmp 0x24c1
movq 0x38(%rsp), %rax
movq 0x40(%rsp), %rcx
movq %rcx, 0x90(%rsp)
movq %rax, 0x98(%rsp)
movl $0x0, 0x8c(%rsp)
movl 0x8c(%rsp), %eax
cmpl 0x27dc(%rsp), %eax
jge 0x25ee
movl $0x0, 0x88(%rsp)
movl 0x88(%rsp), %eax
cmpl 0x27d8(%rsp), %eax
jge 0x25d6
movl $0x0, 0x84(%rsp)
movl 0x84(%rsp), %eax
cmpl 0x27d4(%rsp), %eax
jge 0x25be
leaq 0xa0(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x2ce0
vmovsd %xmm0, 0x30(%rsp)
jmp 0x2555
vmovsd 0x30(%rsp), %xmm1
vcvtsd2ss %xmm1, %xmm0, %xmm0
movq 0x27e0(%rsp), %rax
movl 0x88(%rsp), %ecx
imull 0x27d0(%rsp), %ecx
addl 0x84(%rsp), %ecx
movslq %ecx, %rcx
vmovss %xmm0, (%rax,%rcx,4)
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0x2524
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb8(%rsp)
movl %eax, 0xb4(%rsp)
leaq 0x1448(%rsp), %rdi
callq 0x2d60
jmp 0x26dd
jmp 0x25c0
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x2505
jmp 0x25d8
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0x24e6
callq 0x2c50
movq %rdx, 0x20(%rsp)
movq %rax, 0x28(%rsp)
jmp 0x25ff
movq 0x20(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rcx, 0x70(%rsp)
movq %rax, 0x78(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x2d10
vmovsd %xmm0, 0x18(%rsp)
jmp 0x262d
vmovsd 0x18(%rsp), %xmm0
vmovsd %xmm0, 0x68(%rsp)
vcvtsi2sdl 0x27dc(%rsp), %xmm0, %xmm0
vcvtsi2sdl 0x27d8(%rsp), %xmm1, %xmm1
vmulsd %xmm1, %xmm0, %xmm0
vcvtsi2sdl 0x27d4(%rsp), %xmm1, %xmm1
vmulsd %xmm1, %xmm0, %xmm0
vmovsd %xmm0, 0x60(%rsp)
vmovsd 0x68(%rsp), %xmm0
vmovsd 0x29a0(%rip), %xmm1     # 0x5010
vmulsd %xmm1, %xmm0, %xmm0
vmovsd 0x60(%rsp), %xmm1
vdivsd %xmm1, %xmm0, %xmm0
vmovsd %xmm0, 0x58(%rsp)
movq 0x5945(%rip), %rdi      # 0x7fd0
leaq 0x29a6(%rip), %rsi      # 0x5038
callq 0x2140
movq %rax, 0x10(%rsp)
jmp 0x269e
movq 0x10(%rsp), %rdi
vmovsd 0x58(%rsp), %xmm0
callq 0x2230
movq %rax, 0x8(%rsp)
jmp 0x26b5
movq 0x8(%rsp), %rdi
movq 0x58f7(%rip), %rsi      # 0x7fb8
callq 0x2160
jmp 0x26c8
leaq 0x1448(%rsp), %rdi
callq 0x2d60
addq $0x27e8, %rsp           # imm = 0x27E8
retq
movq 0xb8(%rsp), %rdi
callq 0x2210
nopw (%rax,%rax)