forked from pmkravets/strassen-winograd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
159 lines (141 loc) · 4.26 KB
/
main.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
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//
// main.c
// strassen-winograd
//
// Created by Pavel Kravets on 03.10.13.
// Copyright (c) 2013 Pavel Kravets. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include "matrix.h"
#include "naive.h"
#include "winograd.h"
#include "strassen.h"
#ifdef USE_ORCA
#include "orca-hardware-counters.h"
#else
#include <sys/time.h>
#include <sys/resource.h>
#endif
#ifndef USE_ORCA
double calculate(const struct rusage* b, const struct rusage* a)
{
if (b == NULL || a == NULL)
{
return 0.0;
}
else
{
return ((((a->ru_utime.tv_sec * 1000000 + a->ru_utime.tv_usec) -
(b->ru_utime.tv_sec * 1000000 + b->ru_utime.tv_usec)) +
((a->ru_stime.tv_sec * 1000000 + a->ru_stime.tv_usec) -
(b->ru_stime.tv_sec * 1000000 + b->ru_stime.tv_usec)))
/ 1000000.0);
}
}
#endif
void experiment()
{
#ifdef USE_ORCA
unsigned int N=16;
unsigned int LIMIT=64;
unsigned int before, after;
#else
unsigned int N=64;
unsigned int LIMIT=512;
struct rusage before, after;
#endif
while (N<=LIMIT)
{
#ifdef USE_ORCA
unsigned int M = 1;
unsigned int naive_mult_time = 0;
unsigned int winograd_mult_time = 0;
unsigned int strassen_mult_time = 0;
#else
unsigned int M = (2048 / N);
double naive_mult_time = .0;
double winograd_mult_time = .0;
double strassen_mult_time = .0;
#endif
matrix* m1 = alloc_matrix();
matrix* m2 = alloc_matrix();
matrix* naive_res = alloc_matrix();
matrix* winograd_res = alloc_matrix();
matrix* strassen_res = alloc_matrix();
printf("starting to alloc %dx%d matrix ...\n", N, N);
random_matrix(N, N, m1);
random_matrix(N, N, m2);
printf("allocated!\n");
for(int i = 0; i<M; i++)
{
#ifdef USE_ORCA
before = *CPU_COUNTER_CYCLES_TOTAL;
#else
getrusage(RUSAGE_SELF, &before);
#endif
naive_mult(m1, m2, naive_res);
#ifdef USE_ORCA
after = *CPU_COUNTER_CYCLES_TOTAL;
naive_mult_time += after - before;
#else
getrusage(RUSAGE_SELF, &after);
naive_mult_time += calculate(&before, &after);
#endif
}
naive_mult_time /= M;
printf("naive done!\n");
for(int i = 0; i<M; i++)
{
#ifdef USE_ORCA
before = *CPU_COUNTER_CYCLES_TOTAL;
#else
getrusage(RUSAGE_SELF, &before);
#endif
winograd_mult(m1, m2, winograd_res);
#ifdef USE_ORCA
after = *CPU_COUNTER_CYCLES_TOTAL;
winograd_mult_time += after - before;
#else
getrusage(RUSAGE_SELF, &after);
winograd_mult_time += calculate(&before, &after);
#endif
}
winograd_mult_time /= M;
printf("winograd done!\n");
for(int i = 0; i<M; i++)
{
#ifdef USE_ORCA
before = *CPU_COUNTER_CYCLES_TOTAL;
#else
getrusage(RUSAGE_SELF, &before);
#endif
strassen_mult(m1, m2, strassen_res, 100, 32);
#ifdef USE_ORCA
after = *CPU_COUNTER_CYCLES_TOTAL;
strassen_mult_time += after - before;
#else
getrusage(RUSAGE_SELF, &after);
strassen_mult_time += calculate(&before, &after);
#endif
}
strassen_mult_time /= M;
printf("strassen done!\n");
#ifdef USE_ORCA
printf("{\"N\" : %d, \"naive\" : %d, \"winograd\" : %d, \"strassen\" : %d}\n\n", N, naive_mult_time, winograd_mult_time, strassen_mult_time);
#else
printf("{\"N\" : %d, \"naive\" : %f, \"winograd\" : %f, \"strassen\" : %f}\n\n", N, naive_mult_time, winograd_mult_time, strassen_mult_time);
#endif
free_matrix(m1);
free_matrix(m2);
free_matrix(naive_res);
free_matrix(winograd_res);
free_matrix(strassen_res);
N *= 2;
}
}
int main(int argc, const char * argv[])
{
experiment();
return 0;
}