-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmul_div_hotaka.c
92 lines (73 loc) · 1.77 KB
/
mul_div_hotaka.c
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
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#define LOGIN "hotaka"
long long count;
int loop;
#define LOOP_SEC (2)
static __inline int mul(int x,int y) {
int ans = 0;
while (y) {
// 1. 乗数乗数の最下位ビットが1の場合のみ積レジスタに被乗数を加算
ans += -(y & 1) & x;
// 2. 被乗数を左シフト
x <<= 1;
// 3. 乗数を右シフト
y >>= 1;
}
return ans;
}
static __inline int div(int x,int y) {
int q = 0; // 商
int r = 0; // 剰余
for (int i = 31; i >= 0; i--) {
r = (r << 1) | ((x >> i) & 1); // 剰余を1ビット左シフトし、被除数のiビット目を加算
if (r >= y) {
r -= y; // 剰余から除数を引く
q |= (1 << i); // 商に1を立てる
}
}
return q;
}
void alarm_mul(int signum){
printf("MUL: %lld K instructions/sec\n", count/LOOP_SEC/1000);
loop = 0;
}
void alarm_div(int signum){
printf("DIV: %lld K instructions/sec\n", count/LOOP_SEC/1000);
loop = 0;
}
int main() {
int x,y;
printf("Start (%s program)\n", LOGIN);
// Benchmark MUL
count = 0;
loop = 1;
signal(SIGALRM, alarm_mul);
alarm(LOOP_SEC);
for (x=1; loop ; ++x) {
for (y=1; y<0xffff; ++y) {
if (mul(x,y) != x*y) {
printf("MUL: Calculation results are incorrect. results=%d, expected=%d\n", mul(x,y), x*y);
return(-1);
}
++count;
}
}
// Benchmark DIV
count = 0;
loop = 1;
signal(SIGALRM, alarm_div);
alarm(LOOP_SEC);
for (x=0x0fffffff; loop ; --x) {
for (y=1; y<0xffff; ++y) {
if (div(x,y) != x/y) {
printf("DIV: Calculation results are incorrect. results=%d, expected=%d\n", div(x,y), x/y);
return(-1);
}
++count;
}
}
return 0;
}