-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultisort.c
executable file
·149 lines (119 loc) · 4.36 KB
/
multisort.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
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
double getusec_() {
struct timeval time;
gettimeofday(&time, NULL);
return ((double)time.tv_sec * (double)1e6 + (double)time.tv_usec);
}
#define START_COUNT_TIME stamp = getusec_();
#define STOP_COUNT_TIME(_m) stamp = getusec_() - stamp;\
stamp = stamp/1e6;\
printf ("%s: %0.6f\n",(_m), stamp);
// N and MIN must be powers of 2
long N;
long MIN_SORT_SIZE;
long MIN_MERGE_SIZE;
#define BLOCK_SIZE 1024L
#define T int
void basicsort(long n, T data[n]);
void basicmerge(long n, T left[n], T right[n], T result[n*2], long start, long length);
void merge(long n, T left[n], T right[n], T result[n*2], long start, long length) {
if (length < MIN_MERGE_SIZE*2L) {
// Base case
basicmerge(n, left, right, result, start, length);
} else {
// Recursive decomposition
merge(n, left, right, result, start, length/2);
merge(n, left, right, result, start + length/2, length/2);
}
}
void multisort(long n, T data[n], T tmp[n]) {
if (n >= MIN_SORT_SIZE*4L) {
// Recursive decomposition
multisort(n/4L, &data[0], &tmp[0]);
multisort(n/4L, &data[n/4L], &tmp[n/4L]);
multisort(n/4L, &data[n/2L], &tmp[n/2L]);
multisort(n/4L, &data[3L*n/4L], &tmp[3L*n/4L]);
merge(n/4L, &data[0], &data[n/4L], &tmp[0], 0, n/2L);
merge(n/4L, &data[n/2L], &data[3L*n/4L], &tmp[n/2L], 0, n/2L);
merge(n/2L, &tmp[0], &tmp[n/2L], &data[0], 0, n);
} else {
// Base case
basicsort(n, data);
}
}
static void initialize(long length, T data[length]) {
long i;
for (i = 0; i < length; i++) {
if (i==0) {
data[i] = rand();
} else {
data[i] = ((data[i-1]+1) * i * 104723L) % N;
}
}
}
static void clear(long length, T data[length]) {
long i;
for (i = 0; i < length; i++) {
data[i] = 0;
}
}
void check_sorted(long n, T data[n])
{
int unsorted=0;
for (int i=1; i<n; i++)
if (data[i-1] > data[i]) unsorted++;
if (unsorted > 0)
printf ("\nERROR: data is NOT properly sorted. There are %d unordered positions\n\n",unsorted);
else {
// printf ("data IS ordered; ");
}
}
long N;
long MIN_SORT_SIZE;
long MIN_MERGE_SIZE;
int main(int argc, char **argv) {
/* Defaults for command line arguments */
N = 32768 * BLOCK_SIZE;
MIN_SORT_SIZE = 32 * BLOCK_SIZE;
MIN_MERGE_SIZE = 32 * BLOCK_SIZE;;
/* Process command-line arguments */
for (int i=1; i<argc; i++) {
if (strcmp(argv[i], "-n")==0) {
N = atol(argv[++i]) * BLOCK_SIZE;
}
else if (strcmp(argv[i], "-s")==0) {
MIN_SORT_SIZE = atol(argv[++i]) * BLOCK_SIZE;
}
else if (strcmp(argv[i], "-m")==0) {
MIN_MERGE_SIZE = atol(argv[++i]) * BLOCK_SIZE;
}
else {
fprintf(stderr, "Usage: %s [-n vector_size -s MIN_SORT_SIZE -m MIN_MERGE_SIZE]\n", argv[0]);
fprintf(stderr, " -n to specify the size of the vector (in Kelements) to sort (default 32768)\n");
fprintf(stderr, " -s to specify the size of the vector (in Kelements) that breaks recursion in the sort phase (default 32)\n");
fprintf(stderr, " -m to specify the size of the vector (in Kelements) that breaks recursion in the merge phase (default 32)\n");
return EXIT_FAILURE;
}
}
fprintf(stdout, "Arguments (Kelements): N=%ld, MIN_SORT_SIZE=%ld, MIN_MERGE_SIZE=%ld\n", N/BLOCK_SIZE, MIN_SORT_SIZE/BLOCK_SIZE, MIN_MERGE_SIZE/BLOCK_SIZE);
T *data = malloc(N*sizeof(T));
T *tmp = malloc(N*sizeof(T));
double stamp;
START_COUNT_TIME;
initialize(N, data);
clear(N, tmp);
STOP_COUNT_TIME("Initialization time in seconds");
START_COUNT_TIME;
multisort(N, data, tmp);
STOP_COUNT_TIME("Multisort execution time");
START_COUNT_TIME;
check_sorted (N, data);
STOP_COUNT_TIME("Check sorted data execution time");
fprintf(stdout, "Multisort program finished\n");
return 0;
}