// File: fjamour[P]icentral/src/experiments.cc
// Function: speedup_info(graph_t&, int)
void speedup_info(graph_t& graph, int num_edges_to_insert)
{
    printf("==========================================================\n");
    printf("Graph: \t\t\t%s\n", graph.graph_name.c_str());
    printf("Graph # nodes: \t\t%d\n", graph.size());
    printf("Graph # edges: \t\t%d\n", graph.edge_set.size());
    vector<graph_hash_t> bcc_vec;
    graph.find_bicon_comp(bcc_vec);
    
    int G_s = graph.size() + graph.edge_set.size();
    int G_n                    = graph.size();
    
    vector<edge_t> rand_edge_vec;
    printf("Generating edges...\n");
    for(int i = 0; i < num_edges_to_insert; ++i) {
        edge_t rand_edge;
        node_id_t src, dst;
        do {
            src = rand()%graph.size();
            dst = rand()%graph.size();
            rand_edge.first    = src;
            rand_edge.second   = dst;
        } while(graph.has_edge(rand_edge) ||
                find(rand_edge_vec.begin(), rand_edge_vec.end(), rand_edge) != rand_edge_vec.end());
        rand_edge_vec.push_back(rand_edge);
    }
    
    
    printf("\n");
    vector<double> est_speedup_vec;
    for(int i = 0; i < rand_edge_vec.size(); ++i) {
        node_id_t src = rand_edge_vec[i].first;
        node_id_t dst = rand_edge_vec[i].second;
        graph_hash_t bcc;
        graph.insert_edge(src, dst);
        graph.find_edge_bcc_subgraph(bcc, src, dst);
        graph.remove_edge(src, dst);
        
        int bcc_s = bcc.size() + bcc.edge_set.size();
        int bcc_n = bcc.size();
        
        printf("BCC#nodes:[%*d]   BCC#edges:[%*d]   BCCSizeFrac:[%f]   BCCNodeFrac:[%f]\n",
                8,
                bcc_n,
                8,
                bcc.edge_set.size(),
                (double)bcc_s/G_s,
                (double)bcc_n/graph.size());
        
        int d0, d1, d2;
        bcc.find_pruning_counts_exp(src, dst, d0, d1, d2);
        
        double iter_frac = 1.0 - ((double)d0/bcc_n);
        double est_speedup = 1.0/(((double)bcc_n/G_n) * iter_frac * ((double)bcc_s/G_s));
        
        est_speedup_vec.push_back(est_speedup);
        
        printf("d0:[%*d][%f]   d1:[%*d]    d2:[%*d] -- Edge(%d, %d)\n",
                8,
                d0,
                (double)d0/bcc_n,
                8,
                d1,
                8,
                d2,
                src,
                dst);
        
        printf("\n");
    }
    
    double min, max, median;
    double mean, stddev;
    simple_stats(est_speedup_vec, mean, stddev, median, min, max);
    //estimate of the time it takes to do my long delta iteration
    //to the time it takes the normal iteration
    double long_iter_perc;
    long_iter_perc = 150.0;
    printf("\n");
    printf("Estimate ideal speedups: (delta iter to orig iter [%f])\n",
        long_iter_perc);
    printf("Mean[%f] Stddev[%f] Median[%f] Min[%f] Max[%f]\n",
        mean * (100/long_iter_perc),
        stddev * (100/long_iter_perc),
        median * (100/long_iter_perc),
        min * (100/long_iter_perc),
        max * (100/long_iter_perc));
    
    double worst_mean = mean * (100/long_iter_perc);
    long_iter_perc = 100.0;
    printf("Estimate ideal speedups: (delta iter to orig iter [%f])\n",
        long_iter_perc);
    printf("Mean[%f] Stddev[%f] Median[%f] Min[%f] Max[%f]\n",
        mean * (100/long_iter_perc),
        stddev * (100/long_iter_perc),
        median * (100/long_iter_perc),
        min * (100/long_iter_perc),
        max * (100/long_iter_perc));
    double best_mean = mean * (100/long_iter_perc);
    printf("\n");
    printf("[[Average speedup (ideal): %f - %f]]\n",
        worst_mean,
        best_mean);
}

// Assembly:
subq $0x498, %rsp            # imm = 0x498
movq %rdi, 0x490(%rsp)
movl %esi, 0x48c(%rsp)
leaq 0x2eed3(%rip), %rdi     # 0x7b2e0
xorl %eax, %eax
movb %al, 0xaf(%rsp)
callq 0x9040
movq 0x490(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x9250
movq %rax, %rsi
movb 0xaf(%rsp), %al
leaq 0x2eedc(%rip), %rdi     # 0x7b31c
callq 0x9040
movq 0x490(%rsp), %rdi
callq 0x56b40
movq %rax, %rsi
movb 0xaf(%rsp), %al
leaq 0x2eec7(%rip), %rdi     # 0x7b32a
callq 0x9040
movq 0x490(%rsp), %rdi
addq $0x30, %rdi
callq 0x4dbe0
movq %rax, %rsi
movb 0xaf(%rsp), %al
leaq 0x2eeb5(%rip), %rdi     # 0x7b33f
callq 0x9040
leaq 0x470(%rsp), %rdi
movq %rdi, 0xb0(%rsp)
callq 0x42080
movq 0xb0(%rsp), %rsi
movq 0x490(%rsp), %rdi
callq 0x40080
jmp 0x4c4bb
movq 0x490(%rsp), %rdi
callq 0x56b40
movq %rax, 0xa0(%rsp)
jmp 0x4c4d2
movq 0x490(%rsp), %rdi
addq $0x30, %rdi
callq 0x4dbe0
movq %rax, %rcx
movq 0xa0(%rsp), %rax
addl %ecx, %eax
movl %eax, 0x460(%rsp)
movq 0x490(%rsp), %rdi
callq 0x56b40
movq %rax, 0x98(%rsp)
jmp 0x4c50e
movq 0x98(%rsp), %rax
movl %eax, 0x45c(%rsp)
leaq 0x440(%rsp), %rdi
callq 0x4db80
leaq 0x2ef25(%rip), %rdi     # 0x7b456
xorl %eax, %eax
callq 0x9040
jmp 0x4c53a
movl $0x0, 0x43c(%rsp)
movl 0x43c(%rsp), %eax
cmpl 0x48c(%rsp), %eax
jge 0x4c730
leaq 0x434(%rsp), %rdi
callq 0x41760
jmp 0x4c568
jmp 0x4c56a
callq 0x91a0
cltq
movq %rax, 0x88(%rsp)
movq 0x490(%rsp), %rdi
callq 0x56b40
movq %rax, 0x90(%rsp)
jmp 0x4c590
movq 0x90(%rsp), %rcx
movq 0x88(%rsp), %rax
xorl %edx, %edx
divq %rcx
movl %edx, %eax
movl %eax, 0x430(%rsp)
callq 0x91a0
cltq
movq %rax, 0x78(%rsp)
movq 0x490(%rsp), %rdi
callq 0x56b40
movq %rax, 0x80(%rsp)
jmp 0x4c5d1
movq 0x80(%rsp), %rcx
movq 0x78(%rsp), %rax
xorl %edx, %edx
divq %rcx
movl %edx, %eax
movl %eax, 0x42c(%rsp)
movl 0x430(%rsp), %eax
movl %eax, 0x434(%rsp)
movl 0x42c(%rsp), %eax
movl %eax, 0x438(%rsp)
movq 0x490(%rsp), %rdi
leaq 0x434(%rsp), %rsi
callq 0x57340
movb %al, 0x77(%rsp)
jmp 0x4c623
movb 0x77(%rsp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0x76(%rsp)
jne 0x4c6c3
jmp 0x4c638
leaq 0x440(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0x47550
movq 0x60(%rsp), %rdi
movq %rax, 0x418(%rsp)
callq 0x473d0
movq %rax, 0x410(%rsp)
movq 0x418(%rsp), %rdi
movq 0x410(%rsp), %rsi
leaq 0x434(%rsp), %rdx
callq 0x4db20
movq %rax, 0x68(%rsp)
jmp 0x4c688
movq 0x68(%rsp), %rax
movq %rax, 0x420(%rsp)
leaq 0x440(%rsp), %rdi
callq 0x473d0
movq %rax, 0x408(%rsp)
leaq 0x420(%rsp), %rdi
leaq 0x408(%rsp), %rsi
callq 0x4dae0
movb %al, 0x76(%rsp)
movb 0x76(%rsp), %al
testb $0x1, %al
jne 0x4c56a
leaq 0x440(%rsp), %rdi
leaq 0x434(%rsp), %rsi
callq 0x42130
jmp 0x4c6e6
jmp 0x4c6e8
movl 0x43c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x43c(%rsp)
jmp 0x4c545
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x468(%rsp)
movl %eax, 0x464(%rsp)
jmp 0x4cd4b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x468(%rsp)
movl %eax, 0x464(%rsp)
jmp 0x4cd3e
leaq 0x2f6eb(%rip), %rdi     # 0x7be22
xorl %eax, %eax
callq 0x9040
jmp 0x4c740
leaq 0x3f0(%rsp), %rdi
callq 0xfa00
movl $0x0, 0x3ec(%rsp)
movslq 0x3ec(%rsp), %rax
movq %rax, 0x58(%rsp)
leaq 0x440(%rsp), %rdi
callq 0x47680
movq %rax, %rcx
movq 0x58(%rsp), %rax
cmpq %rcx, %rax
jae 0x4cacc
movslq 0x3ec(%rsp), %rsi
leaq 0x440(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x4dbc0
movq 0x50(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0x3e8(%rsp)
movslq 0x3ec(%rsp), %rsi
callq 0x4dbc0
movl 0x4(%rax), %eax
movl %eax, 0x3e4(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x41780
jmp 0x4c7d1
movq 0x490(%rsp), %rdi
movl 0x3e8(%rsp), %esi
movl 0x3e4(%rsp), %edx
callq 0x56720
jmp 0x4c7ee
movq 0x490(%rsp), %rdi
movl 0x3e8(%rsp), %edx
movl 0x3e4(%rsp), %ecx
leaq 0x138(%rsp), %rsi
callq 0x409c0
jmp 0x4c813
movq 0x490(%rsp), %rdi
movl 0x3e8(%rsp), %esi
movl 0x3e4(%rsp), %edx
callq 0x56850
jmp 0x4c830
leaq 0x138(%rsp), %rdi
callq 0x52790
movq %rax, 0x48(%rsp)
jmp 0x4c844
leaq 0x168(%rsp), %rdi
callq 0x4dbe0
movq %rax, %rcx
movq 0x48(%rsp), %rax
addl %ecx, %eax
movl %eax, 0x134(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x52790
movq %rax, 0x40(%rsp)
jmp 0x4c876
movq 0x40(%rsp), %rax
movl %eax, 0x130(%rsp)
movl 0x130(%rsp), %eax
movl %eax, 0x1c(%rsp)
leaq 0x168(%rsp), %rdi
callq 0x4dbe0
movq %rax, 0x20(%rsp)
cvtsi2sdl 0x134(%rsp), %xmm0
cvtsi2sdl 0x460(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
cvtsi2sdl 0x130(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x490(%rsp), %rdi
callq 0x56b40
movq %rax, 0x38(%rsp)
jmp 0x4c8de
movsd 0x28(%rsp), %xmm0
movq 0x20(%rsp), %r8
movl 0x1c(%rsp), %edx
movsd 0x30(%rsp), %xmm1
movq 0x38(%rsp), %rax
movq %rax, %xmm2
movaps 0x2e9ac(%rip), %xmm3    # 0x7b2b0
punpckldq %xmm3, %xmm2    # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
movapd 0x2e9b0(%rip), %xmm3    # 0x7b2c0
subpd %xmm3, %xmm2
movaps %xmm2, %xmm3
unpckhpd %xmm2, %xmm2            # xmm2 = xmm2[1,1]
addsd %xmm3, %xmm2
divsd %xmm2, %xmm1
leaq 0x2f15f(%rip), %rdi     # 0x7ba89
movl $0x8, %ecx
movb $0x2, %al
movl %ecx, %esi
callq 0x9040
jmp 0x4c93a
movl 0x3e8(%rsp), %esi
movl 0x3e4(%rsp), %edx
leaq 0x138(%rsp), %rdi
leaq 0x12c(%rsp), %rcx
leaq 0x128(%rsp), %r8
leaq 0x124(%rsp), %r9
callq 0x53700
jmp 0x4c96f
cvtsi2sdl 0x12c(%rsp), %xmm2
cvtsi2sdl 0x130(%rsp), %xmm0
divsd %xmm0, %xmm2
movsd 0x2e683(%rip), %xmm0    # 0x7b010
movaps %xmm0, %xmm1
subsd %xmm2, %xmm1
movsd %xmm1, 0x118(%rsp)
cvtsi2sdl 0x130(%rsp), %xmm1
cvtsi2sdl 0x45c(%rsp), %xmm2
divsd %xmm2, %xmm1
movsd 0x118(%rsp), %xmm2
mulsd %xmm2, %xmm1
cvtsi2sdl 0x134(%rsp), %xmm2
cvtsi2sdl 0x460(%rsp), %xmm3
divsd %xmm3, %xmm2
mulsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x110(%rsp)
leaq 0x3f0(%rsp), %rdi
leaq 0x110(%rsp), %rsi
callq 0x4de20
jmp 0x4c9fe
movl 0x12c(%rsp), %edx
cvtsi2sd %edx, %xmm0
cvtsi2sdl 0x130(%rsp), %xmm1
divsd %xmm1, %xmm0
movl 0x128(%rsp), %r8d
movl 0x124(%rsp), %ecx
movl 0x3e8(%rsp), %esi
movl 0x3e4(%rsp), %edi
movq %rsp, %rax
movl %edi, 0x10(%rax)
movl %esi, 0x8(%rax)
movl %ecx, (%rax)
leaq 0x2efa6(%rip), %rdi     # 0x7b9eb
movl $0x8, %r9d
movb $0x1, %al
movl %r9d, %esi
movl %r9d, %ecx
callq 0x9040
jmp 0x4ca5a
leaq 0x2f3c1(%rip), %rdi     # 0x7be22
xorl %eax, %eax
callq 0x9040
jmp 0x4ca6a
leaq 0x138(%rsp), %rdi
callq 0x41f20
movl 0x3ec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3ec(%rsp)
jmp 0x4c758
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x468(%rsp)
movl %eax, 0x464(%rsp)
jmp 0x4cd31
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x468(%rsp)
movl %eax, 0x464(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x41f20
jmp 0x4cd31
leaq 0xd0(%rsp), %rdi
leaq 0x3f0(%rsp), %rsi
callq 0x4de90
jmp 0x4cae3
leaq 0xd0(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
leaq 0xe8(%rsp), %rdx
leaq 0xf8(%rsp), %rcx
leaq 0x108(%rsp), %r8
leaq 0x100(%rsp), %r9
callq 0x78710
jmp 0x4cb1a
leaq 0xd0(%rsp), %rdi
callq 0xfa50
movabsq $0x4062c00000000000, %rax # imm = 0x4062C00000000000
movq %rax, 0xc8(%rsp)
leaq 0x2f2e2(%rip), %rdi     # 0x7be22
xorl %eax, %eax
callq 0x9040
jmp 0x4cb49
movsd 0xc8(%rsp), %xmm0
leaq 0x2eef7(%rip), %rdi     # 0x7ba50
movb $0x1, %al
callq 0x9040
jmp 0x4cb62
movsd 0xf0(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm1
movsd 0x2e71c(%rip), %xmm5    # 0x7b298
divsd %xmm1, %xmm5
mulsd %xmm5, %xmm0
movsd 0xe8(%rsp), %xmm1
mulsd %xmm5, %xmm1
movsd 0xf8(%rsp), %xmm2
mulsd %xmm5, %xmm2
movsd 0x108(%rsp), %xmm3
mulsd %xmm5, %xmm3
movsd 0x100(%rsp), %xmm4
mulsd %xmm5, %xmm4
leaq 0x2ee61(%rip), %rdi     # 0x7ba20
movb $0x5, %al
callq 0x9040
jmp 0x4cbc8
movsd 0xf0(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm2
movsd 0x2e6b6(%rip), %xmm1    # 0x7b298
divsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0xc0(%rsp)
movabsq $0x4059000000000000, %rax # imm = 0x4059000000000000
movq %rax, 0xc8(%rsp)
movsd 0xc8(%rsp), %xmm0
leaq 0x2ee3b(%rip), %rdi     # 0x7ba50
movb $0x1, %al
callq 0x9040
jmp 0x4cc1e
movsd 0xf0(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm1
movsd 0x2e660(%rip), %xmm5    # 0x7b298
divsd %xmm1, %xmm5
mulsd %xmm5, %xmm0
movsd 0xe8(%rsp), %xmm1
mulsd %xmm5, %xmm1
movsd 0xf8(%rsp), %xmm2
mulsd %xmm5, %xmm2
movsd 0x108(%rsp), %xmm3
mulsd %xmm5, %xmm3
movsd 0x100(%rsp), %xmm4
mulsd %xmm5, %xmm4
leaq 0x2eda5(%rip), %rdi     # 0x7ba20
movb $0x5, %al
callq 0x9040
jmp 0x4cc84
movsd 0xf0(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm2
movsd 0x2e5fa(%rip), %xmm1    # 0x7b298
divsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0xb8(%rsp)
leaq 0x2f16c(%rip), %rdi     # 0x7be22
xorl %eax, %eax
callq 0x9040
jmp 0x4ccbf
movsd 0xc0(%rsp), %xmm0
movsd 0xb8(%rsp), %xmm1
leaq 0x2edfa(%rip), %rdi     # 0x7bad2
movb $0x2, %al
callq 0x9040
jmp 0x4cce1
leaq 0x3f0(%rsp), %rdi
callq 0xfa50
leaq 0x440(%rsp), %rdi
callq 0x4dc40
leaq 0x470(%rsp), %rdi
callq 0x421a0
addq $0x498, %rsp            # imm = 0x498
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x468(%rsp)
movl %eax, 0x464(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0xfa50
leaq 0x3f0(%rsp), %rdi
callq 0xfa50
leaq 0x440(%rsp), %rdi
callq 0x4dc40
leaq 0x470(%rsp), %rdi
callq 0x421a0
movq 0x468(%rsp), %rdi
callq 0x9cf0
nopw %cs:(%rax,%rax)