forked from PancakeTY/cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreduction_integral.cpp
More file actions
153 lines (121 loc) · 3.55 KB
/
Copy pathreduction_integral.cpp
File metadata and controls
153 lines (121 loc) · 3.55 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <cstdio>
#include <omp.h>
#include <faasm/shared_mem.h>
#define NTHREADS 10
bool checkResult(const char* func, double reduction)
{
if (reduction < 3 || reduction > 4) {
printf("Function %s didn't return pi but %f\n", func, reduction);
return true;
}
return false;
}
double roundRobin()
{
int nthreads;
long nSteps = 100000000;
double pi = 0.0;
double sum[NTHREADS];
double step = 1.0 / (double)nSteps;
double timerStart = omp_get_wtime();
omp_set_num_threads(NTHREADS);
#pragma omp parallel default(none) shared(nthreads, nSteps, step, sum)
{
int lnthreads = omp_get_num_threads();
int id = omp_get_thread_num();
if (id == 0) {
nthreads = lnthreads;
}
sum[id] = 0;
for (int i = id; i < nSteps; i += lnthreads) {
double x = (i + 0.5) * step;
sum[id] += 4.0 / (1.0 + x * x);
}
}
printf("RR calculating pi over %i threads\n", nthreads);
for (int i = 0; i < nthreads; ++i) {
pi += sum[i] * step;
}
double timerEnd = omp_get_wtime() - timerStart;
printf("RR took %f, pi: %f\n", timerEnd, pi);
return pi;
}
double doAtomic()
{
long nSteps = 100000000;
double pi = 0.0;
double step = 1.0 / (double)nSteps;
double timerStart = omp_get_wtime();
omp_set_num_threads(4);
#pragma omp parallel default(none) shared(nSteps, step, pi)
{
int i, id, lnthreads;
double x, sum = 0;
lnthreads = omp_get_num_threads();
id = omp_get_thread_num();
for (i = id; i < nSteps; i += lnthreads) {
x = (i + 0.5) * step;
sum += 4.0 / (1.0 + x * x);
}
FAASM_ATOMIC_INCR_BY(pi, sum * step);
}
double timerEnd = omp_get_wtime() - timerStart;
printf("Atomic took %f, pi: %f\n", timerEnd, pi);
return pi;
}
double doReduction()
{
long nSteps = 100000000;
double step = 0;
double pi = 0.0;
double sum = 0;
int i = 0;
step = 1.0 / (double)nSteps;
omp_set_num_threads(NTHREADS);
double timerStart = omp_get_wtime();
FAASM_REDUCE(sum, FAASM_TYPE_DOUBLE, FAASM_OP_SUM)
#pragma omp parallel for default(none) shared(nSteps, step) reduction(+ : sum)
for (i = 0; i < nSteps; ++i) {
int x = (i + 0.5) * step;
sum += 4.0 / (1.0 + x * x);
}
pi = sum * step;
double timerEnd = omp_get_wtime() - timerStart;
printf("Reduction took %f, pi: %f\n", timerEnd, pi);
return pi;
}
double doBetterReduction()
{
// This version is better because it can work in non-threaded environments.
long nSteps = 100000000;
double step = 0;
double pi = 0.0;
double sum = 0;
int i = 0, x;
step = 1.0 / (double)nSteps;
omp_set_num_threads(NTHREADS);
double timerStart = omp_get_wtime();
FAASM_REDUCE(sum, FAASM_TYPE_DOUBLE, FAASM_OP_SUM)
#pragma omp parallel for private(x) default(none) shared(nSteps, step) \
reduction(+ : sum)
for (i = 0; i < nSteps; ++i) {
x = (i + 0.5) * step;
sum += 4.0 / (1.0 + x * x);
}
pi = sum * step;
double timerEnd = omp_get_wtime() - timerStart;
printf("Better reduction took %f, pi: %f\n", timerEnd, pi);
return pi;
}
int main(int argc, char* argv[])
{
bool failed = false;
failed |= checkResult("Atomic", doAtomic());
failed |= checkResult("RR", roundRobin());
failed |= checkResult("Reduction", doReduction());
failed |= checkResult("Better reduction", doBetterReduction());
if (failed) {
return 1;
}
return 0;
}