-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
136 lines (122 loc) · 2.84 KB
/
main.cpp
File metadata and controls
136 lines (122 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <stdio.h>
#include <windows.h>
#define MAX_ITER 1000000000
__forceinline unsigned GetVal()
{
return rand() % 100 + 1;
}
/* original equation
a * i + b * (c + i) + d * (j + i)
i, j - loop dependent
a, b, c, d - constants
*/
/* opitimized equation
(a + b + d) * i + b * c + d * j
Allows b * c and (a + b + d) to be calculated out of loop
*/
unsigned calc_cpp(unsigned a, unsigned b, unsigned c, unsigned d)
{
unsigned res = 0, i = 0, j = MAX_ITER;
// Assuming, n > 0
do
{
res += (a + b + d) * i + b * c + d * j;
--j;
} while (++i < MAX_ITER);
return res;
}
// UNOPTIMIZED READABLE VERSION
//
// unsigned calc_asm(unsigned a, unsigned b, unsigned c, unsigned d)
//{
// __asm
// {
// // ecx = b * c
// mov ebx, b
// mov eax, c
// mul ebx // ebx (b) * eax (c) (result: first 32bit in eax, last 32bit in edx)
// mov ecx, eax
// // ebx = a + b
// add ebx, a
// // edx = d * MAX_ITER
// mov edx, d
// mov eax, MAX_ITER
// mul edx // edx (d) * eax (MAX_ITER) (result: first 32bit in eax, last 32bit in edx)
// mov edx, eax
// // edx (d * MAX_ITER) += ecx (b * c)
// add edx, ecx
// // ecx = MAX_ITER
// mov ecx, MAX_ITER
// // eax = 0
// xor eax, eax
//
// /*
// eax = 0
// ebx = a + b
// ecx = MAX_ITER
// edx = d * MAX_ITER + b * c
// */
//
// CNT:
// // eax += edx (d * j + b * c)
// // edx += ebx (a + b)
// add eax, edx
// add edx, ebx
// dec ecx // same as -> sub ecx, 1
// jnz CNT
// }
// // return eax (4byte value)
// }
unsigned calc_asm(unsigned a, unsigned b, unsigned c, unsigned d)
{
__asm
{
// ecx = b * c
mov ebx, b
mov eax, c
mul ebx // ebx (b) * eax (c) (result: first 32bit in eax, last 32bit in edx)
mov edx, d
mov ecx, eax
// ebx = a + b
add ebx, a
// edx = d * MAX_ITER
mov eax, MAX_ITER
mul edx // edx (d) * eax (MAX_ITER) (result: first 32bit in eax, last 32bit in edx)
mov edx, eax
// edx (d * MAX_ITER) += ecx (b * c)
add edx, ecx
// ecx = MAX_ITER
mov ecx, MAX_ITER
// eax = 0
xor eax, eax
/*
eax = 0
ebx = a + b
ecx = MAX_ITER
edx = d * MAX_ITER + b * c
*/
CNT:
// eax += edx (d * j + b * c)
// edx += ebx (a + b)
add eax, edx
add edx, ebx
dec ecx // same as -> sub ecx, 1
jnz CNT
}
// return eax (4byte value)
}
int main()
{
unsigned a = GetVal(), b = GetVal(), c = GetVal(), d = GetVal();
printf("Constants: a=%u\tb=%u\tc=%u\td=%u\n\n", a, b, c, d);
printf("LAB RESULTS for (a + b + d) * i + b * c + d * j:\n");
DWORD time_st = GetTickCount();
printf("Result = %u\n", calc_cpp(a, b, c, d));
time_st = GetTickCount() - time_st;
printf("Work time of %u iterations of cpp code = %u ms\n", MAX_ITER, time_st);
time_st = GetTickCount();
printf("\nResult = %u\n", calc_asm(a, b, c, d));
time_st = GetTickCount() - time_st;
printf("Work time of %u iterations of asm code = %u ms\n", MAX_ITER, time_st);
return 0;
}