-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
123 lines (108 loc) · 2.9 KB
/
main.cpp
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
/**
* @file main.cpp
* @class main
* @author Liliana O'Sullivan
* @brief An implementation of the Sieve of Eratosthenes using OpenMP.
* @version 0.1
* @date 12th February 2021
* @copyright MIT License
*
*/
#include <iostream>
#include <chrono>
#include <omp.h>
#include <math.h>
using namespace std;
/**
* @brief A sequencial implementation of the Sieve. Uses a stack based sieve. This segment-faults at a high value of N. Eg 1 Billion
*
* @param n The value to calculate primes up to.
* @return long Amount of twin primes found up to N.
*/
long sequential_stack(long long n)
{
bool a[n];
for (long long i = 0L; i < n; ++i)
a[i] = true;
for (long long i = 2; i * i <= n; ++i)
if (a[i])
for (long long j = i * i; j <= n; j += i)
a[j] = false;
long count = 0L;
for (long long i = 3; i < n - 2; i+=2)
{
if (a[i] and a[i + 2])
{
cout << "(" << i << "," << i + 2 << ")" << endl;
count++;
}
}
cout << "\t\tSequential_stack: " << count << endl;
return count;
}
/**
* @brief A sequencial implementation of the Sieve. Uses a heap based sieve.
*
* @param n The value to calculate primes up to.
* @return long Amount of twin primes found up to N.
*/
long sequential_heap(long long n)
{
bool *a = new bool[n];
for (long long i = 0L; i < n; ++i)
a[i] = true;
for (long long i = 2; i * i <= n; ++i)
if (a[i])
for (long long j = i * 2; j <= n; j += i)
a[j] = false;
long count = 0L;
for (long long i = 3; i < n - 2; i+=2)
{
if (a[i] and a[i + 2])
count++;
}
cout << "\t\tSequential_heap: " << count << endl;
delete[] a;
return count;
}
/**
* @brief A concurrent implementation of the Sieve. Uses a heap based sieve.
*
* @param n The value to calculate primes up to.
* @return long Amount of twin primes found up to N.
*/
long concurrent(long long n)
{
bool *a = new bool[n];
// omp_set_num_threads(1);
#pragma omp parallel for
for (int i = 0; i < n; ++i)
a[i] = true; // Assume all numbers prime by default
const unsigned long n_sqrt = sqrt(n);
#pragma omp parallel for schedule(dynamic) // Dynamic scheduling greatly increased performance
for (long long i = 2; i <= n_sqrt; ++i)
if (a[i]) // If its a prime, mark multiples as none-prime
for (long long j = i * 2; j <= n; j += i)
a[j] = false;
unsigned long count = 0L;
#pragma omp parallel for schedule(static)
for (long long i = 3; i < n - 2; i+=2)
{
if (a[i] and a[i + 2])
{
#pragma omp critical
count++;
}
}
delete[] a;
cout << "\t\tConcurrent: " << count << endl;
return count;
}
int main()
{
long long n = 500000000;
// cin >> n;
//sequential_heap(n);
concurrent(n);
return 0;
}