-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmysort.cpp
More file actions
213 lines (187 loc) · 5.44 KB
/
Copy pathmysort.cpp
File metadata and controls
213 lines (187 loc) · 5.44 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <cstdlib>
#include <fstream>
#include <thread>
#include <algorithm>
#include <string>
#include <omp.h>
#include "arg_parser.h"
using namespace std;
/* execution time struct */
typedef chrono::high_resolution_clock Clock;
/* merge sort functions */
void mergeOpenMP(int *arr, int low, int high, int mid, int len);
void mergeSortOpenMP(int *arr, int low, int high, int len);
void merge(int *arr, int low, int high, int mid, int len);
void mergeSort(int *arr, int low, int high, int len);
/* array sort check */
void arrayCheck(int asize, int *a1, int *a2);
/* =============================================== */
/* ===================== MAIN ==================== */
int main(int argc, const char* argv[]){
struct arg_params args_parsed = arg_parser(argc, argv);
string inputFile = args_parsed.inputFile;
string outputFile = args_parsed.outputFile;
// create array from input file
fstream file(inputFile.c_str(), ios_base::in);
int a, b = 0;
int arrsize = 0;
string line;
while (getline(file, line)) arrsize++;
int arr[arrsize], arr2[arrsize], arrCheck[arrsize];
fstream infile(inputFile, ios_base::in);
while (infile >> a) {
arr[b] = arr2[b] = arrCheck[b]= a;
b++;
}
// execution start time
auto start_time = Clock::now();
// OpenMP mergesort
mergeSortOpenMP(arr, 0, arrsize - 1, arrsize);
// execution end time
auto end_time = Clock::now();
/* The follow is setup for execution time comparison */
// // execution start time
// auto start_time2 = Clock::now();
// // mergesort
// mergeSort(arr2, 0, arrsize - 1, arrsize);
// // execution end time
// auto end_time2 = Clock::now();
// calculate and display execution time
unsigned long time_spent = chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
printf("Time elapsed: %lu nanoseconds\n", time_spent);
printf(" %f seconds\n", time_spent/1e9);
/* Determine which sorting algo is faster */
// unsigned long time_spent2 = chrono::duration_cast<chrono::nanoseconds>(end_time2 - start_time2).count();
// printf(" %f seconds\n", time_spent2/1e9);
// float time_diff = float(time_spent) / float(time_spent2);
// if (time_diff < 1) printf("OpenMP is %f times faster than normal mergesort.\n", abs(1-time_diff) + 1);
// else printf("Normal mergesort is %f times faster than OpenMP.\n", time_diff);
/* WRITE SORTED ARRAY TO FILE */
ofstream outfile;
outfile.open(outputFile);
for (int i = 0; i < arrsize; i++) outfile << arr[i] << endl;
outfile.close();
// ensure array was sorted
sort(arrCheck, arrCheck + arrsize);
arrayCheck(arrsize, arr, arrCheck);
}
/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ MERGE SORT ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
void mergeOpenMP(int *arr, int low, int high, int mid, int len) {
int i, j, k, c[len];
i = low;
k = low;
j = mid + 1;
// attempt to parellize this block of code {}
#pragma omp parallel
{
// omp_get_thread_num();
// single thread, since reliant on ordering/incrementing
#pragma omp single
{
while (i <= mid && j <= high) {
if (arr[i] < arr[j]) {
c[k] = arr[i];
i++;
} else {
c[k] = arr[j];
j++;
}
k++;
}
}
// single thread, since reliant on ordering/incrementing
#pragma omp single
{
while (i <= mid) {
c[k] = arr[i];
k++;
i++;
}
}
// single thread, since reliant on ordering/incrementing
#pragma omp single
{
while (j <= high) {
c[k] = arr[j];
k++;
j++;
}
}
#pragma omp for
for (i = low; i < k; i++) {
arr[i] = c[i];
}
} // end omp parallel
}
void mergeSortOpenMP(int *arr, int low, int high, int len) {
if (low < high){
//divide the array at mid and sort independently using merge sort
int mid=(low+high)/2;
// split in two sections
#pragma omp parallel sections
{
#pragma omp section
mergeSortOpenMP(arr,low,mid,len);
#pragma omp section
mergeSortOpenMP(arr,mid+1,high,len);
}
//merge or conquer sorted arrays
mergeOpenMP(arr,low,high,mid,len);
}
}
// Merge sort, from lab0
void merge(int *arr, int low, int high, int mid, int len) {
int i, j, k, c[len];
i = low;
k = low;
j = mid + 1;
while (i <= mid && j <= high) {
if (arr[i] < arr[j]) {
c[k] = arr[i];
k++;
i++;
}
else {
c[k] = arr[j];
k++;
j++;
}
}
while (i <= mid) {
c[k] = arr[i];
k++;
i++;
}
while (j <= high) {
c[k] = arr[j];
k++;
j++;
}
for (i = low; i < k; i++) {
arr[i] = c[i];
}
}
void mergeSort(int *arr, int low, int high, int len) {
if (low < high){
//divide the array at mid and sort independently using merge sort
int mid=(low+high)/2;
mergeSort(arr,low,mid,len);
mergeSort(arr,mid+1,high,len);
//merge or conquer sorted arrays
merge(arr,low,high,mid,len);
}
}
/* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ END MERGE SORT ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
//check if array sorted correctly - by comparing two sorted arrays
void arrayCheck(int asize, int *a1, int *a2) {
for (int i = 0; i < asize; i++) {
if (a1[i] != a2[i]) {
printf("Array is incorrectly sorted!\n%i != %i at position %i\n", a1[i], a2[i], i);
return;
}
}
}