Skip to content

Commit 777945e

Browse files
authored
Merge branch 'main' into fix-failing-array-tests
2 parents 3917c4d + 6b820ea commit 777945e

21 files changed

+557
-118
lines changed

benchrunner/Benchrunner.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,12 @@ dobench bench parorseq mb_size iters = do
218218
unless (isSorted (res0)) (error $ show bench ++ ": result not sorted.")
219219
putStrLn "Sorted: OK"
220220
pure (length arr, length res0, tmed0, tall0)
221+
CxxSort alg -> do
222+
arr <- getInputAsList alg mb_size
223+
(res0, tmed0, tall0) <- M.benchAndRunCxxSorts alg arr iters
224+
unless (isSorted (res0)) (error $ show bench ++ ": result not sorted.")
225+
putStrLn "Sorted: OK"
226+
pure (length arr, length res0, tmed0, tall0)
221227
_ -> error "dobench: case not implemented!"
222228

223229
{-

benchrunner/ForeignFunctionImports.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module ForeignFunctionImports (c_insertionsort, c_mergesort, c_quicksort, SortFn) where
1+
module ForeignFunctionImports (c_insertionsort, c_mergesort, c_quicksort, cxx_int_insertionsort, cxx_int_mergesort, cxx_int_quicksort, SortFn, SortFnCxx) where
22

33
import Foreign as F
44
import Foreign.C.Types as CTypes
@@ -9,3 +9,8 @@ type SortFn = Ptr Int64 -> CTypes.CSize -> CTypes.CSize -> IO (Ptr Int64)
99
foreign import ccall "insertionsort_inplace" c_insertionsort :: SortFn
1010
foreign import ccall "smergesort" c_mergesort :: SortFn
1111
foreign import ccall "quicksort_inplace" c_quicksort :: SortFn
12+
13+
type SortFnCxx = Ptr Int64 -> CTypes.CSize -> IO (Ptr Int64)
14+
foreign import ccall "insertionsort_cxx_int" cxx_int_insertionsort :: SortFnCxx
15+
foreign import ccall "bottom_up_merge_sort_cxx_int" cxx_int_mergesort :: SortFnCxx
16+
foreign import ccall "quicksort_cxx_int" cxx_int_quicksort :: SortFnCxx

benchrunner/Measure.hs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module Measure (benchAndRunCSorts, benchAndRunDataVecSorts, benchOnArrays, bench, benchPar, dotrialIO, benchIO, benchParIO) where
1+
module Measure (benchAndRunCSorts, benchAndRunCxxSorts, benchAndRunDataVecSorts, benchOnArrays, bench, benchPar, dotrialIO, benchIO, benchParIO) where
22

33
import Control.Exception (evaluate)
44
import Control.Monad.Par hiding (runParIO)
@@ -157,6 +157,13 @@ sortFnC alg = case alg of
157157
Quicksort -> FFI.c_quicksort
158158
_ -> error "sortFnC: Csort not implemented!"
159159

160+
sortFnCxx :: SortAlgo -> FFI.SortFnCxx
161+
sortFnCxx alg = case alg of
162+
Insertionsort -> FFI.cxx_int_insertionsort
163+
Mergesort -> FFI.cxx_int_mergesort
164+
Quicksort -> FFI.cxx_int_quicksort
165+
_ -> error "sortFnCxx: Csort not implemented!"
166+
160167
-- return type : IO ([Int64], Double, Double)
161168
-- [Int64]: sorted output array from the last iteration that was run
162169
-- Double: median runtime from the iterations that were run (selftimed)
@@ -184,3 +191,31 @@ benchAndRunCSorts salg arr iters = do
184191
putStrLn ("iter time: " ++ show delt)
185192
!sortedArr <- peekArray arrLength (castPtr sortedPtr :: Ptr Int64)
186193
return $! (sortedArr, delt)
194+
195+
-- return type : IO ([Int64], Double, Double)
196+
-- [Int64]: sorted output array from the last iteration that was run
197+
-- Double: median runtime from the iterations that were run (selftimed)
198+
-- Double: Total time taken to run all the iterations (batchtime)
199+
benchAndRunCxxSorts :: SortAlgo -> [Int64] -> Int -> IO ([Int64], Double, Double)
200+
benchAndRunCxxSorts salg arr iters = do
201+
!tups <- mapM (\_ -> do
202+
!ptr <- newArray arr
203+
res <- dotrialCxx salg (length arr) ptr
204+
pure res
205+
) [1..iters]
206+
let (results, times) = unzip tups
207+
-- print times
208+
let selftimed = median times
209+
batchtime = sum times
210+
return $! (last results, selftimed, batchtime)
211+
where
212+
dotrialCxx alg arrLength ptr = do
213+
performMajorGC
214+
let fn = sortFnCxx alg
215+
t1 <- getCurrentTime
216+
!sortedPtr <- fn ptr (fromIntegral arrLength)
217+
t2 <- getCurrentTime
218+
let delt = fromRational (toRational (diffUTCTime t2 t1))
219+
putStrLn ("iter time: " ++ show delt)
220+
!sortedArr <- peekArray arrLength (castPtr sortedPtr :: Ptr Int64)
221+
return $! (sortedArr, delt)

benchrunner/Types.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ data Benchmark
2323
| OurSort SortAlgo
2424
| VectorSort SortAlgo
2525
| CSort SortAlgo
26+
| CxxSort SortAlgo
2627
deriving (Eq, Show, Read)
2728

2829
data ParOrSeq = Seq | Par | ParM

benchrunner/benchrunner.cabal

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
cabal-version: >=1.10
2-
1+
cabal-version: 2.2
32
name: benchrunner
43
version: 0.1
54
build-type: Simple
@@ -33,14 +32,28 @@ executable benchrunner
3332
ghc-options: -Wall -Wcompat
3433
-threaded -rtsopts
3534
-fdefer-typed-holes
36-
-O2
35+
-O2 -optl -optl-lstdc++
36+
37+
extra-libraries: stdc++
3738

3839
c-sources:
3940
csorts/insertionsort.c
4041
csorts/mergesort.c
4142
csorts/quicksort.c
4243

44+
cxx-sources:
45+
cxx/insertionsort.cpp
46+
cxx/mergesort.cpp
47+
cxx/quicksort.cpp
48+
cxx/insertionsort_int_wrapper.cpp
49+
cxx/mergesort_int_wrapper.cpp
50+
cxx/quicksort_int_wrapper.cpp
51+
52+
build-depends: system-cxx-std-lib
53+
4354
-- DNDEBUG disables asserts in cbits/
4455
cc-options: -std=c11 -O3 -DNDEBUG=1
4556
-fno-strict-aliasing
4657
-Werror=undef
58+
59+
cpp-options: -std=c++11 -O3 -fno-strict-aliasing

benchrunner/cxx/Makefile

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
CFILES = $(wildcard *.c) $(wildcard *.cpp)
2+
OBJFILES = $(CFILES:.cpp=.o)
3+
OUT = cbench.exe
4+
5+
USECLANG := 0
6+
DEBUG := 0
7+
CILK := 0
8+
9+
ifeq ($(CILK), 1)
10+
ifeq ($(USECLANG), 0)
11+
$(error cilk can only be used with an opencilk compiler!)
12+
endif
13+
endif
14+
15+
OpenCILK_CLANG := clang-16
16+
OpenCILK_CLANG_FLAGS := -std=gnu11 -DCILK -fopencilk -fPIC
17+
CLANG := clang++
18+
CLANG_FLAGS := -std=c++11 -lm -fPIC
19+
GCC := g++
20+
GCC_FLAGS := -std=c++11 -lm -fPIC
21+
22+
CC := $(GCC)
23+
CFLAGS := $(GCC_FLAGS)
24+
CDEBUG := -DCBENCH_DEBUG -O0 -g
25+
26+
CFLAGS += -Wall -Wextra -Wpedantic -flto
27+
28+
ifeq ($(USECLANG), 1)
29+
CC = $(CLANG)
30+
CFLAGS = $(CLANG_FLAGS)
31+
LFLAGS := -fuse-ld=lld
32+
endif
33+
34+
ifeq ($(CILK), 1)
35+
ifeq ($(USECLANG), 1)
36+
CC = $(OpenCILK_CLANG)
37+
CFLAGS = $(OpenCILK_CLANG_FLAGS)
38+
LFLAGS := -fuse-ld=lld
39+
endif
40+
endif
41+
42+
ifeq ($(DEBUG), 1)
43+
CFLAGS += $(CDEBUG)
44+
else
45+
CFLAGS += -O3
46+
endif
47+
48+
all: $(OUT)
49+
50+
$(OUT): $(OBJFILES)
51+
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
52+
53+
%.o: %.c
54+
$(CC) $(CFLAGS) -c -o $@ $^
55+
56+
clean:
57+
rm -f $(OUT) *.o
58+
59+
.PHONY: clean

benchrunner/cxx/benchmarks.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef _BENCHMARKS_H
2+
#define _BENCHMARKS_H
3+
4+
#include <stdlib.h>
5+
#include <stdint.h>
6+
#include <iostream>
7+
#include <chrono>
8+
9+
// Copied from stdlib.h for reference.
10+
typedef int (*__compar_fn_t) (const void *, const void *);
11+
12+
// Sorting algorithms.
13+
template<typename T> T *insertionsort_inplace(T *pbase, size_t total_elems);
14+
template<typename T> T *quicksort_inplace(T *_a, size_t n);
15+
template<typename T> T *bottomUpMergeSort(T *a, T *b, int n);
16+
template<typename T> void bottomUpMerge(T *a, int left, int right, int end, T *b);
17+
template<typename T> void copyArray(T *b, T* a, int n);
18+
19+
// Relating to C++ templatized versions
20+
extern "C" {
21+
extern int64_t *bottom_up_merge_sort_cxx_int(int64_t *pbase, size_t total_elems);
22+
extern int64_t *insertionsort_cxx_int(int64_t *pbase, size_t total_elems);
23+
extern int64_t *quicksort_cxx_int(int64_t *pbase, size_t total_elems);
24+
}
25+
26+
// Microbenchmarks.
27+
int64_t* __attribute__ ((noinline)) fill_array_rand_seq(size_t total_elems);
28+
29+
#endif

benchrunner/cxx/helpers.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef _HELPERS_H
2+
#define _HELPERS_H
3+
4+
#include <stdlib.h>
5+
#include <stdio.h>
6+
#include <stdint.h>
7+
#include <stdbool.h>
8+
#include <string.h>
9+
#include <errno.h>
10+
#include <time.h>
11+
#include <assert.h>
12+
13+
int64_t* __attribute__ ((noinline)) fill_array_rand_seq(size_t total_elems)
14+
{
15+
void *nums;
16+
nums = (int64_t*) malloc(total_elems * sizeof(int64_t));
17+
if (nums == NULL) {
18+
fprintf(stderr, "Couldn't allocate memory for output array.\n");
19+
return NULL;
20+
}
21+
int64_t *elt = (int64_t *) nums;
22+
for (uint64_t i = 0; i <= total_elems-1; i++) {
23+
elt = (int64_t*) nums + i;
24+
*elt = rand();
25+
}
26+
return (int64_t *) nums;
27+
}
28+
29+
static inline void slice_assert_sorted(int64_t *arr, int size)
30+
{
31+
size_t len = size;
32+
int64_t a, b;
33+
for (size_t i = 0; i < len-1; i++) {
34+
a = arr[i];
35+
b = arr[i+1];
36+
if (a > b) {
37+
fprintf(stderr, "Elements at %zu and %zu are not sorted.", i, i+1);
38+
exit(1);
39+
}
40+
}
41+
printf("Sorted: OK\n");
42+
}
43+
44+
#endif

benchrunner/cxx/insertionsort.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "benchmarks.h"
2+
3+
// -----------------------------------------------------------------------------
4+
// i ← 1
5+
// while i < n
6+
// temp ← array[i]
7+
// j ← i
8+
// while j > 0 and array[j - 1] > temp
9+
// array[j] ← array[j - 1]
10+
// j ← j - 1
11+
// end while
12+
// array[j] ← temp
13+
// i ← i + 1
14+
// end while
15+
16+
template<typename T>
17+
T *insertionsort_inplace(T *pbase, size_t total_elems)
18+
{
19+
int i = 0;
20+
while (i < total_elems){
21+
T temp = pbase[i];
22+
int j = i;
23+
while(j > 0 && pbase[j - 1] > temp){
24+
pbase[j] = pbase[j-1];
25+
j = j - 1;
26+
}
27+
pbase[j] = temp;
28+
i = i + 1;
29+
}
30+
31+
return pbase;
32+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "benchmarks.h"
2+
#include "insertionsort.cpp"
3+
4+
extern "C" {
5+
extern int64_t *insertionsort_cxx_int(int64_t *pbase, size_t total_elems){
6+
return insertionsort_inplace<int64_t>(pbase, total_elems);
7+
}
8+
}

0 commit comments

Comments
 (0)