Przeglądaj źródła

refrator; tests

master
Robin Thoni 7 lat temu
rodzic
commit
41dd97b4b6
21 zmienionych plików z 179 dodań i 135 usunięć
  1. 8
    15
      Makefile
  2. 3
    0
      benchmark.sh
  3. 16
    2
      common.c
  4. 1
    0
      common.h
  5. 26
    8
      d2p.c
  6. 7
    0
      d2p.h
  7. 38
    8
      d2s.c
  8. 8
    0
      d2s.h
  9. 62
    0
      main.c
  10. 0
    41
      mergepar.c
  11. 0
    6
      mergepar.h
  12. 0
    41
      mergeseq.c
  13. 0
    6
      mergeseq.h
  14. BIN
      omp-merge-sort
  15. 1
    8
      test.sh
  16. 2
    0
      tests/05.in
  17. 1
    0
      tests/05.out
  18. 2
    0
      tests/06.in
  19. 1
    0
      tests/06.out
  20. 2
    0
      tests/07.in
  21. 1
    0
      tests/07.out

+ 8
- 15
Makefile Wyświetl plik

@@ -1,30 +1,23 @@
1 1
 CFLAGS = -Wall -Wextra -Werror -pedantic -std=c99 -fopenmp
2 2
 LDLIBS = -lrt
3 3
 CC = gcc
4
-SOURCES_COMMON = common.c mergeseq.c mergepar.c
5
-SOURCES_SEQ = $(SOURCES_COMMON) d2s.c
6
-OUT_SEQ = omp-merge-sort-seq
7
-OBJS_SEQ = $(SOURCES_SEQ:.c=.o)
8
-SOURCES_PAR = $(SOURCES_COMMON) d2p.c
9
-OUT_PAR = omp-merge-sort-par
10
-OBJS_PAR = $(SOURCES_PAR:.c=.o)
4
+SOURCES = common.c d2s.c d2p.c main.c
5
+OUT = omp-merge-sort
6
+OBJS = $(SOURCES:.c=.o)
11 7
 
12 8
 all: release
13 9
 
14 10
 debug: CFLAGS += -g3 -ggdb3
15
-debug: $(OUT_SEQ) $(OUT_PAR)
11
+debug: $(OUT)
16 12
 
17 13
 release: CFLAGS += -o3
18
-release: $(OUT_SEQ) $(OUT_PAR)
14
+release: $(OUT)
19 15
 
20
-$(OUT_SEQ): $(OBJS_SEQ)
21
-	  $(LINK.c) $(OUTPUT_OPTION) $(OBJS_SEQ) $(LDLIBS)
22
-
23
-$(OUT_PAR): $(OBJS_PAR)
24
-	  $(LINK.c) $(OUTPUT_OPTION) $(OBJS_PAR) $(LDLIBS)
16
+$(OUT): $(OBJS)
17
+	  $(LINK.c) $(OUTPUT_OPTION) $(OBJS) $(LDLIBS)
25 18
 
26 19
 clean:
27 20
 	  rm -f *.o
28 21
 
29 22
 distclean: clean
30
-	  rm -f *.a $(OUT_SEQ) $(OUT_PAR)
23
+	  rm -f *.a $(OUT)

+ 3
- 0
benchmark.sh Wyświetl plik

@@ -0,0 +1,3 @@
1
+#! /usr/bin/env sh
2
+
3
+cat tests/*.in | ./omp-merge-sort --no-array

+ 16
- 2
common.c Wyświetl plik

@@ -3,6 +3,11 @@
3 3
 #include <stdlib.h>
4 4
 #include <unistd.h>
5 5
 
6
+unsigned get_cpu_count(void)
7
+{
8
+    return (unsigned)sysconf(_SC_NPROCESSORS_ONLN);
9
+}
10
+
6 11
 struct timespec get_time(void)
7 12
 {
8 13
     struct timespec start_time;
@@ -42,7 +47,9 @@ int* read_int_array(unsigned n)
42 47
 {
43 48
   int* array = (int*)malloc(n * sizeof(unsigned));
44 49
   for (unsigned i = 0; i < n; ++i) {
45
-    scanf("%i", &array[i]);
50
+    if (scanf("%i", &array[i]) == EOF) {
51
+      return 0;
52
+    }
46 53
   }
47 54
   return array;
48 55
 }
@@ -52,11 +59,18 @@ void read_input(int** array, unsigned* n)
52 59
   if (isatty(0)) {
53 60
     printf("Enter n: ");
54 61
   }
55
-  scanf("%u", n);
62
+  if (scanf("%u", n) == EOF) {
63
+    *array = 0;
64
+    *n = 0;
65
+    return;
66
+  }
56 67
   if (isatty(0)) {
57 68
     printf("Enter %u integers: ", 2 * *n);
58 69
   }
59 70
   *array = read_int_array(2 * *n);
71
+  if (!*array) {
72
+    *n = 0;
73
+  }
60 74
 }
61 75
 
62 76
 void print_array(int* array, unsigned n)

+ 1
- 0
common.h Wyświetl plik

@@ -4,6 +4,7 @@
4 4
 #define _POSIX_C_SOURCE 199309L
5 5
 #include <time.h>
6 6
 
7
+unsigned get_cpu_count(void);
7 8
 struct timespec get_time(void);
8 9
 struct timespec time_diff(struct timespec* ts1, struct timespec* ts2);
9 10
 struct timespec get_duration(struct timespec* ts);

+ 26
- 8
d2p.c Wyświetl plik

@@ -1,12 +1,30 @@
1
+#include "d2p.h"
1 2
 #include "common.h"
2
-#include "mergepar.h"
3
+#include "d2s.h"
3 4
 
4
-int main(void)
5
+void merge_sort_sub_par(int* array, unsigned l, unsigned h, unsigned threads)
5 6
 {
6
-  int* array;
7
-  unsigned n;
8
-  read_input(&array, &n);
9
-  merge_sort_par(array, 2 * n);
10
-  print_array(array, 2 * n);
11
-  return 0;
7
+  if (l < h) {
8
+    unsigned m = (l + h) / 2;
9
+    if (threads > 1) {
10
+      unsigned n = threads / 2;
11
+      #pragma omp parallel sections
12
+      {
13
+        #pragma omp section
14
+        merge_sort_sub_par(array, l, m, threads);
15
+        #pragma omp section
16
+        merge_sort_sub_par(array, m + 1, h, threads - n);
17
+      }
18
+    }
19
+    else {
20
+      merge_sort_sub_seq(array, l, m);
21
+      merge_sort_sub_seq(array, m + 1, h);
22
+    }
23
+    merge_sort_merge_seq(array, l, m, h);
24
+  }
25
+}
26
+
27
+void merge_sort_par(int* array, unsigned s, unsigned threads)
28
+{
29
+  merge_sort_sub_par(array, 0, s - 1, threads);
12 30
 }

+ 7
- 0
d2p.h Wyświetl plik

@@ -0,0 +1,7 @@
1
+#ifndef D2P_H
2
+#define D2P_H
3
+
4
+void merge_sort_sub_par(int* array, unsigned l, unsigned h, unsigned threads);
5
+void merge_sort_par(int* array, unsigned s, unsigned threads);
6
+
7
+#endif

+ 38
- 8
d2s.c Wyświetl plik

@@ -1,12 +1,42 @@
1
+#include "d2s.h"
1 2
 #include "common.h"
2
-#include "mergeseq.h"
3 3
 
4
-int main(void)
4
+void merge_sort_merge_seq(int* array, unsigned l, unsigned m, unsigned h)
5 5
 {
6
-  int* array;
7
-  unsigned n;
8
-  read_input(&array, &n);
9
-  merge_sort_seq(array, 2 * n);
10
-  print_array(array, 2 * n);
11
-  return 0;
6
+  unsigned i = l, j = m + 1, k = 0;
7
+  int tmp[h - l + 1];
8
+  while (i <= m && j <= h) {
9
+    if (array[i] <= array[j]) {
10
+      tmp[k++] = array[i++];
11
+    }
12
+    else {
13
+      tmp[k++] = array[j++];
14
+    }
15
+  }
16
+
17
+  while (i <= m) {
18
+    tmp[k++] = array[i++];
19
+  }
20
+  while (j <= h) {
21
+    tmp[k++] = array[j++];
22
+  }
23
+
24
+  for (--k; k != (unsigned)-1; --k) {
25
+    array[l + k] = tmp[k];
26
+  }
27
+}
28
+
29
+void merge_sort_sub_seq(int* array, unsigned l, unsigned h)
30
+{
31
+  if (l < h) {
32
+    unsigned m = (l + h) / 2;
33
+    merge_sort_sub_seq(array, l, m);
34
+    merge_sort_sub_seq(array, m + 1, h);
35
+    merge_sort_merge_seq(array, l, m, h);
36
+  }
37
+}
38
+
39
+void merge_sort_seq(int* array, unsigned s)
40
+{
41
+  merge_sort_sub_seq(array, 0, s - 1);
12 42
 }

+ 8
- 0
d2s.h Wyświetl plik

@@ -0,0 +1,8 @@
1
+#ifndef D2S_H
2
+#define D2S_H
3
+
4
+void merge_sort_merge_seq(int* array, unsigned l, unsigned m, unsigned h);
5
+void merge_sort_sub_seq(int* array, unsigned l, unsigned h);
6
+void merge_sort_seq(int* array, unsigned s);
7
+
8
+#endif

+ 62
- 0
main.c Wyświetl plik

@@ -0,0 +1,62 @@
1
+#define _POSIX_C_SOURCE 199309L
2
+#include <stdio.h>
3
+#include <string.h>
4
+#include <time.h>
5
+#include "common.h"
6
+#include "d2s.h"
7
+#include "d2p.h"
8
+
9
+int main(int argc, char** argv)
10
+{
11
+  int oprint_stats = 1;
12
+  int oprint_array = 1;
13
+  int otest = 0;
14
+
15
+  for (int i = 1; i < argc; ++i) {
16
+    if (!strcmp("--no-stats", argv[i])) {
17
+      oprint_stats = 0;
18
+    }
19
+    else if (!strcmp("--no-array", argv[i])) {
20
+      oprint_array = 0;
21
+    }
22
+    else if (!strcmp("--test", argv[i])) {
23
+      otest = 1;
24
+    }
25
+  }
26
+  if (otest) {
27
+    oprint_stats = 0;
28
+    oprint_array = 1;
29
+  }
30
+
31
+  int* array;
32
+  unsigned n;
33
+  unsigned threads[3] = {0, 12, 24};
34
+  unsigned threads_count = (otest ? 1 : sizeof(threads) / sizeof(*threads));
35
+
36
+  do {
37
+    read_input(&array, &n);
38
+    if (array && n) {
39
+      for (unsigned t = 0; t < threads_count; ++t) {
40
+        unsigned thread_count = threads[t];
41
+        struct timespec start = get_time();
42
+        if (thread_count == 0) {
43
+          merge_sort_seq(array, 2 * n);
44
+        }
45
+        else {
46
+          merge_sort_par(array, 2 * n, thread_count);
47
+        }
48
+        struct timespec ts = get_duration(&start);
49
+        if (oprint_array) {
50
+          print_array(array, 2 * n);
51
+        }
52
+        if (oprint_stats) {
53
+          printf("%3dcpu %3dthreads %6d ", get_cpu_count(), thread_count, n);
54
+          print_time(&ts);
55
+          printf("\n");
56
+        }
57
+      }
58
+    }
59
+  } while (array && n);
60
+
61
+  return 0;
62
+}

+ 0
- 41
mergepar.c Wyświetl plik

@@ -1,41 +0,0 @@
1
-#include "common.h"
2
-
3
-void merge_sort_merge_par(int* array, unsigned l, unsigned m, unsigned h)
4
-{
5
-  unsigned i = l, j = m + 1, k = 0;
6
-  int tmp[h - l + 1];
7
-  while (i <= m && j <= h) {
8
-    if (array[i] <= array[j]) {
9
-      tmp[k++] = array[i++];
10
-    }
11
-    else {
12
-      tmp[k++] = array[j++];
13
-    }
14
-  }
15
-
16
-  while (i <= m) {
17
-    tmp[k++] = array[i++];
18
-  }
19
-  while (j <= h) {
20
-    tmp[k++] = array[j++];
21
-  }
22
-
23
-  for (--k; k != (unsigned)-1; --k) {
24
-    array[l + k] = tmp[k];
25
-  }
26
-}
27
-
28
-void merge_sort_sub_par(int* array, unsigned l, unsigned h)
29
-{
30
-  if (l < h) {
31
-    unsigned m = (l + h) / 2;
32
-    merge_sort_sub_par(array, l, m);
33
-    merge_sort_sub_par(array, m + 1, h);
34
-    merge_sort_merge_par(array, l, m, h);
35
-  }
36
-}
37
-
38
-void merge_sort_par(int* array, unsigned s)
39
-{
40
-  merge_sort_sub_par(array, 0, s - 1);
41
-}

+ 0
- 6
mergepar.h Wyświetl plik

@@ -1,6 +0,0 @@
1
-#ifndef MERGEPAR_H
2
-#define MERGEPAR_H
3
-
4
-void merge_sort_par(int* array, unsigned s);
5
-
6
-#endif

+ 0
- 41
mergeseq.c Wyświetl plik

@@ -1,41 +0,0 @@
1
-#include "common.h"
2
-
3
-void merge_sort_merge_seq(int* array, unsigned l, unsigned m, unsigned h)
4
-{
5
-  unsigned i = l, j = m + 1, k = 0;
6
-  int tmp[h - l + 1];
7
-  while (i <= m && j <= h) {
8
-    if (array[i] <= array[j]) {
9
-      tmp[k++] = array[i++];
10
-    }
11
-    else {
12
-      tmp[k++] = array[j++];
13
-    }
14
-  }
15
-
16
-  while (i <= m) {
17
-    tmp[k++] = array[i++];
18
-  }
19
-  while (j <= h) {
20
-    tmp[k++] = array[j++];
21
-  }
22
-
23
-  for (--k; k != (unsigned)-1; --k) {
24
-    array[l + k] = tmp[k];
25
-  }
26
-}
27
-
28
-void merge_sort_sub_seq(int* array, unsigned l, unsigned h)
29
-{
30
-  if (l < h) {
31
-    unsigned m = (l + h) / 2;
32
-    merge_sort_sub_seq(array, l, m);
33
-    merge_sort_sub_seq(array, m + 1, h);
34
-    merge_sort_merge_seq(array, l, m, h);
35
-  }
36
-}
37
-
38
-void merge_sort_seq(int* array, unsigned s)
39
-{
40
-  merge_sort_sub_seq(array, 0, s - 1);
41
-}

+ 0
- 6
mergeseq.h Wyświetl plik

@@ -1,6 +0,0 @@
1
-#ifndef MERGESEQ_H
2
-#define MERGESEQ_H
3
-
4
-void merge_sort_seq(int* array, unsigned s);
5
-
6
-#endif

BIN
omp-merge-sort Wyświetl plik


+ 1
- 8
test.sh Wyświetl plik

@@ -1,15 +1,10 @@
1 1
 #! /usr/bin/env sh
2 2
 
3
-for exe in omp-merge-sort-seq omp-merge-sort-par
4
-do
5
-
6
-echo "Running ${exe}"
7
-
8 3
 for tIn in tests/*.in
9 4
 do
10 5
   tOut=$(echo "${tIn}" | sed -re 's/(.+).in/\1/')".out"
11 6
   tmpfile=$(mktemp)
12
-  cat "${tIn}" | "./${exe}" > "${tmpfile}"
7
+  cat "${tIn}" | ./omp-merge-sort --test > "${tmpfile}"
13 8
   cmp "${tmpfile}" "${tOut}"
14 9
   res=$?
15 10
   if [ ${res} -ne 0 ]
@@ -20,5 +15,3 @@ do
20 15
     rm "${tmpfile}"
21 16
   fi
22 17
 done
23
-
24
-done

+ 2
- 0
tests/05.in
Plik diff jest za duży
Wyświetl plik


+ 1
- 0
tests/05.out
Plik diff jest za duży
Wyświetl plik


+ 2
- 0
tests/06.in
Plik diff jest za duży
Wyświetl plik


+ 1
- 0
tests/06.out
Plik diff jest za duży
Wyświetl plik


+ 2
- 0
tests/07.in
Plik diff jest za duży
Wyświetl plik


+ 1
- 0
tests/07.out
Plik diff jest za duży
Wyświetl plik


Ładowanie…
Anuluj
Zapisz