// File: akshithasriraman[P]Accelerometer/accelerometer.cc
// Function: main
int main (int argc, char** argv) {
    if (argc != 2) {
        std::cout << "Format: <./binary> <input file name e.g., validation/aesni.txt>\n";
        exit(0);
    }

    // First read user input to get file containing model parameters.
    std::string parameters_file_name = argv[1];
    std::ifstream parameters_file(parameters_file_name);
    if (!parameters_file.good()) {
        std::cout << "Invalid file: file does not exist\n";
        exit(0);
    }


    // Read file to populate model parameter values.
    std::string line = "";
    int dimension = 0, curr_dimension = 0;

    // Process each file line.
    for(int i = 0; std::getline(parameters_file, line); i++)
    {
        std::istringstream buf(line);
        std::istream_iterator<std::string> begin(buf), end;
        std::vector<std::string> tokens(begin, end);
        // We only need model parameter and its value, error out otherwise.
        if (tokens.size() != 2) {
            std::cout << "input file has the wrong format\n";
            exit(0);
        }

        // Populate model values from the file to global vars.
        switch (i)
        {
        case 0:
            C = atol(tokens[1].c_str());
            break;
        case 1:
            alpha = atof(tokens[1].c_str());
            break;
        case 2:
            n = atol(tokens[1].c_str());
            break;
        case 3:
            o_0 = atol(tokens[1].c_str());
            break;
        case 4:
            Q = atol(tokens[1].c_str());
            break;
        case 5:
            L = atol(tokens[1].c_str());
            break;
        case 6:
            o_1 = atol(tokens[1].c_str());
            break;
        case 7:
            A = atof(tokens[1].c_str());
            break;
        case 8:
            threading = tokens[1];
            break;
        default:
            std::cout << "File can have only 8 lines containing model values\n";
            exit(0);
        } 
    }
    // std::cout << C << " " << alpha << " " << n << " " << o_0 << " " << Q << " " << L << " " << o_1 << " " << A << " " << std::endl;

        // Compute speedup based on the threading model.
        if (threading == "Sync") {
            Sync();
        } else if (threading == "Sync-OS") {
            SyncOS();
        } else if (threading == "Async") {
            Async();
        } else {
            std::cout << "Invalid threading option\n";
            exit(0);
        }


        std::cout << "Estimated speedup in % = " << (speedup - 1.0) * 100.0 << "%\n\n" << std::endl;


        
    return 0;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x540, %rsp            # imm = 0x540
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x26a9
movq 0x5942(%rip), %rdi      # 0x7fd8
leaq 0x29ab(%rip), %rsi      # 0x5048
callq 0x2180
xorl %edi, %edi
callq 0x2210
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x4f0(%rbp)
leaq -0x31(%rbp), %rdi
movq %rdi, -0x4e8(%rbp)
callq 0x22e0
movq -0x4f0(%rbp), %rsi
movq -0x4e8(%rbp), %rdx
leaq -0x30(%rbp), %rdi
callq 0x2db0
jmp 0x26e1
leaq -0x31(%rbp), %rdi
callq 0x21d0
leaq -0x250(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x8, %edx
callq 0x2290
jmp 0x2701
movq -0x250(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x250(%rbp,%rax), %rdi
callq 0x22c0
movb %al, -0x4f1(%rbp)
jmp 0x2721
movb -0x4f1(%rbp), %al
testb $0x1, %al
jne 0x2785
jmp 0x272d
movq 0x58a4(%rip), %rdi      # 0x7fd8
leaq 0x294e(%rip), %rsi      # 0x5089
callq 0x2180
jmp 0x2742
xorl %edi, %edi
callq 0x2210
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x31(%rbp), %rdi
callq 0x21d0
jmp 0x2da7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2d9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2d92
leaq -0x271(%rbp), %rdi
movq %rdi, -0x500(%rbp)
callq 0x22e0
movq -0x500(%rbp), %rdx
leaq 0x29a5(%rip), %rsi      # 0x514b
leaq -0x270(%rbp), %rdi
callq 0x2db0
jmp 0x27b4
leaq -0x271(%rbp), %rdi
callq 0x21d0
movl $0x0, -0x278(%rbp)
movl $0x0, -0x27c(%rbp)
movl $0x0, -0x280(%rbp)
leaq -0x250(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x2050
movq %rax, -0x508(%rbp)
jmp 0x27fa
movq -0x508(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x2240
movb %al, -0x509(%rbp)
jmp 0x2818
movb -0x509(%rbp), %al
testb $0x1, %al
jne 0x2827
jmp 0x2c22
leaq -0x400(%rbp), %rdi
leaq -0x270(%rbp), %rsi
movl $0x8, %edx
callq 0x22b0
jmp 0x2841
leaq -0x430(%rbp), %rdi
leaq -0x400(%rbp), %rsi
callq 0x2e60
jmp 0x2856
leaq -0x460(%rbp), %rdi
callq 0x2ec0
jmp 0x2864
leaq -0x4a8(%rbp), %rdi
leaq -0x430(%rbp), %rsi
callq 0x2f00
jmp 0x2879
leaq -0x4d8(%rbp), %rdi
leaq -0x460(%rbp), %rsi
callq 0x2f00
jmp 0x288e
leaq -0x4d9(%rbp), %rdi
movq %rdi, -0x518(%rbp)
callq 0x2f50
movq -0x518(%rbp), %rcx
leaq -0x478(%rbp), %rdi
leaq -0x4a8(%rbp), %rsi
leaq -0x4d8(%rbp), %rdx
callq 0x2f70
jmp 0x28c4
leaq -0x4d9(%rbp), %rdi
callq 0x3070
leaq -0x4d8(%rbp), %rdi
callq 0x3090
leaq -0x4a8(%rbp), %rdi
callq 0x3090
leaq -0x478(%rbp), %rdi
callq 0x30b0
cmpq $0x2, %rax
je 0x29db
movq 0x56d3(%rip), %rdi      # 0x7fd8
leaq 0x27a0(%rip), %rsi      # 0x50ac
callq 0x2180
jmp 0x2913
xorl %edi, %edi
callq 0x2210
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x271(%rbp), %rdi
callq 0x21d0
jmp 0x2d92
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2d86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2c11
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2c05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2bf9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x29ad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x4d9(%rbp), %rdi
callq 0x3070
leaq -0x4d8(%rbp), %rdi
callq 0x3090
leaq -0x4a8(%rbp), %rdi
callq 0x3090
jmp 0x2bf9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x478(%rbp), %rdi
callq 0x30f0
jmp 0x2bf9
movl -0x280(%rbp), %eax
movq %rax, -0x520(%rbp)
subq $0x8, %rax
ja 0x2b99
movq -0x520(%rbp), %rax
leaq 0x2624(%rip), %rcx      # 0x5024
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2200
movq %rax, 0x5787(%rip)      # 0x81b8
jmp 0x2bb5
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2230
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x5785(%rip)     # 0x81e8
jmp 0x2bb5
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2200
movq %rax, 0x5730(%rip)      # 0x81c0
jmp 0x2bb5
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2200
movq %rax, 0x570b(%rip)      # 0x81c8
jmp 0x2bb5
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2200
movq %rax, 0x56e6(%rip)      # 0x81d0
jmp 0x2bb5
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2200
movq %rax, 0x56c1(%rip)      # 0x81d8
jmp 0x2bb5
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2200
movq %rax, 0x569c(%rip)      # 0x81e0
jmp 0x2bb5
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2230
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x567d(%rip)     # 0x81f0
jmp 0x2bb5
leaq -0x478(%rbp), %rdi
movl $0x1, %esi
callq 0x30d0
movq %rax, %rsi
leaq 0x5668(%rip), %rdi      # 0x81f8
callq 0x2030
jmp 0x2b97
jmp 0x2bb5
movq 0x5438(%rip), %rdi      # 0x7fd8
leaq 0x2526(%rip), %rsi      # 0x50cd
callq 0x2180
jmp 0x2bae
xorl %edi, %edi
callq 0x2210
leaq -0x478(%rbp), %rdi
callq 0x30f0
leaq -0x460(%rbp), %rdi
callq 0x3090
leaq -0x430(%rbp), %rdi
callq 0x3090
leaq -0x400(%rbp), %rdi
callq 0x20f0
movl -0x280(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x280(%rbp)
jmp 0x27de
leaq -0x460(%rbp), %rdi
callq 0x3090
leaq -0x430(%rbp), %rdi
callq 0x3090
leaq -0x400(%rbp), %rdi
callq 0x20f0
jmp 0x2d86
leaq 0x55cf(%rip), %rdi      # 0x81f8
leaq 0x24d1(%rip), %rsi      # 0x5101
callq 0x3150
movb %al, -0x521(%rbp)
jmp 0x2c3d
movb -0x521(%rbp), %al
testb $0x1, %al
jne 0x2c49
jmp 0x2c50
callq 0x24e0
jmp 0x2ccc
leaq 0x55a1(%rip), %rdi      # 0x81f8
leaq 0x24a8(%rip), %rsi      # 0x5106
callq 0x3150
movb %al, -0x522(%rbp)
jmp 0x2c6b
movb -0x522(%rbp), %al
testb $0x1, %al
jne 0x2c77
jmp 0x2c7e
callq 0x2570
jmp 0x2cca
leaq 0x5573(%rip), %rdi      # 0x81f8
leaq 0x2482(%rip), %rsi      # 0x510e
callq 0x3150
movb %al, -0x523(%rbp)
jmp 0x2c99
movb -0x523(%rbp), %al
testb $0x1, %al
jne 0x2ca5
jmp 0x2cac
callq 0x25f0
jmp 0x2cc8
movq 0x5325(%rip), %rdi      # 0x7fd8
leaq 0x245a(%rip), %rsi      # 0x5114
callq 0x2180
jmp 0x2cc1
xorl %edi, %edi
callq 0x2210
jmp 0x2cca
jmp 0x2ccc
movq 0x5305(%rip), %rdi      # 0x7fd8
leaq 0x2454(%rip), %rsi      # 0x512e
callq 0x2180
movq %rax, -0x530(%rbp)
jmp 0x2ce8
movq -0x530(%rbp), %rdi
movss 0x54f5(%rip), %xmm0     # 0x81ec
cvtss2sd %xmm0, %xmm0
movsd 0x230d(%rip), %xmm1     # 0x5010
addsd %xmm1, %xmm0
movsd 0x2309(%rip), %xmm1     # 0x5018
mulsd %xmm1, %xmm0
callq 0x2300
movq %rax, -0x538(%rbp)
jmp 0x2d21
movq -0x538(%rbp), %rdi
leaq 0x2419(%rip), %rsi      # 0x5148
callq 0x2180
movq %rax, -0x540(%rbp)
jmp 0x2d3d
movq -0x540(%rbp), %rdi
movq 0x5275(%rip), %rsi      # 0x7fc0
callq 0x21b0
jmp 0x2d52
movl $0x0, -0x4(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x2328
leaq -0x250(%rbp), %rdi
callq 0x2060
leaq -0x30(%rbp), %rdi
callq 0x2328
movl -0x4(%rbp), %eax
addq $0x540, %rsp            # imm = 0x540
popq %rbp
retq
leaq -0x270(%rbp), %rdi
callq 0x2328
leaq -0x250(%rbp), %rdi
callq 0x2060
leaq -0x30(%rbp), %rdi
callq 0x2328
movq -0x40(%rbp), %rdi
callq 0x22d0