From 114f38cbb6e9037b1d8c706abf814f1518a4c579 Mon Sep 17 00:00:00 2001 From: Jeehoon Kang Date: Wed, 1 Jul 2020 14:23:41 +0900 Subject: [PATCH] Add benchmark --- README.md | 10 ++++- bench/.gitignore | 3 ++ bench/Makefile | 28 ++++++++++++++ bench/driver.cpp | 75 +++++++++++++++++++++++++++++++++++++ bench/exotic_arguments.c | 31 +++++++++++++++ bench/fibonacci.c | 20 ++++++++++ bench/two_dimension_array.c | 24 ++++++++++++ 7 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 bench/.gitignore create mode 100644 bench/Makefile create mode 100644 bench/driver.cpp create mode 100644 bench/exotic_arguments.c create mode 100644 bench/fibonacci.c create mode 100644 bench/two_dimension_array.c diff --git a/README.md b/README.md index 940c8f8..71d636a 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ doesn't, please run the fuzzer in Ubuntu 18.04 or 20.04. ```sh # Ubuntu 20.04 or higher -apt install gcc-10-riscv64-linux-gnu qemu-user-static +apt install gcc-10-riscv64-linux-gnu g++-10-riscv64-linux-gnu qemu-user-static ``` ### Cross-Compilation and Architecture-Emulation @@ -143,6 +143,14 @@ echo $? ``` +## Run Benchmark for Performance Competition + +```sh +cd bench +make run +``` + + ## Submission - Submit the corresponding files to [gg.kaist.ac.kr](https://gg.kaist.ac.kr). diff --git a/bench/.gitignore b/bench/.gitignore new file mode 100644 index 0000000..e71133f --- /dev/null +++ b/bench/.gitignore @@ -0,0 +1,3 @@ +/.depend +/bench +*.o diff --git a/bench/Makefile b/bench/Makefile new file mode 100644 index 0000000..58e497f --- /dev/null +++ b/bench/Makefile @@ -0,0 +1,28 @@ +CC=riscv64-linux-gnu-gcc-10 +CXX=riscv64-linux-gnu-g++-10 +KECC=../target/release/kecc +CFLAGS=-O +RM=rm -f + +SRCS=$(shell find . -name "*.c") +OBJS=$(subst .c,.s,$(SRCS)) + +all: bench + +bench: $(OBJS) driver.o + $(CXX) -o bench $(OBJS) driver.o + +run: bench + qemu-riscv64-static -L /usr/riscv64-linux-gnu ./bench + +driver.o: driver.cpp + $(CXX) $(CFLAGS) -o driver.o -c -I. driver.cpp + +.c.s: + ($(KECC) -O $< >$@) || (rm $@ -rf; exit 1) + +$(KECC): + cargo build --manifest-path=../Cargo.toml --release --bin kecc + +clean: + $(RM) $(OBJS) driver.o bench diff --git a/bench/driver.cpp b/bench/driver.cpp new file mode 100644 index 0000000..ad8a96d --- /dev/null +++ b/bench/driver.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace model { + #include + #include + #include +} + +extern "C" { + int exotic_arguments_struct_small(model::small, int); + long exotic_arguments_struct_large(model::large, int); + float exotic_arguments_float(float, int); + double exotic_arguments_double(double, int); + int fibonacci_recursive(int, int); + int fibonacci_loop(int, int); + int two_dimension_array(int, int); +} + +namespace { + inline unsigned long read_cycles() + { + unsigned long cycles; + asm volatile ("rdcycle %0" : "=r" (cycles)); + return cycles; + } + + template + inline unsigned long evaluate(const char *name, I input, O (*solution)(I, int), O (*model)(I, int)) { + std::cout << "[" << name << "] "; + + int nonce = 1 + (std::rand() % 100); + auto start = read_cycles(); + auto output = solution(input, nonce); + auto end = read_cycles(); + + auto expected = model(input, nonce); + if (output != expected) { + std::cout << "mismatched result (expected: " << expected << ", actual: " << output << ")" << std::endl; + std::exit(1); + } + + auto cycles = end - start; + std::cout << cycles << std::endl; + return cycles; + } +} + +int main() { + std::srand(static_cast(time(NULL))); + + std::vector cycles; + + cycles.push_back(evaluate("exotic_arguments_struct_small", model::small { .a = 3, .b = 4 }, exotic_arguments_struct_small, model::exotic_arguments_struct_small)); + cycles.push_back(evaluate("exotic_arguments_struct_large", model::large { .a = 5, .b = 6, .c = 7, .d = 8, .e = 9, .f = 10, .g = 11, .h = 12 }, exotic_arguments_struct_large, model::exotic_arguments_struct_large)); + cycles.push_back(evaluate("exotic_arguments_float", 0.42f, exotic_arguments_float, model::exotic_arguments_float)); + cycles.push_back(evaluate("exotic_arguments_double", 0.42, exotic_arguments_double, model::exotic_arguments_double)); + cycles.push_back(evaluate("fibonacci_recursive", 30, fibonacci_recursive, model::fibonacci_recursive)); + cycles.push_back(evaluate("fibonacci_loop", 30, fibonacci_loop, model::fibonacci_loop)); + cycles.push_back(evaluate("two_dimension_array", 100, two_dimension_array, model::two_dimension_array)); + + double average = 1.0; + for (auto cycle: cycles) { + average *= static_cast(cycle); + } + average = std::pow(average, 1 / static_cast(cycles.size())); + + std::cout << "[AVERAGE] " << average << std::endl; + return 0; +} diff --git a/bench/exotic_arguments.c b/bench/exotic_arguments.c new file mode 100644 index 0000000..8007659 --- /dev/null +++ b/bench/exotic_arguments.c @@ -0,0 +1,31 @@ +typedef struct { + int a; + int b; +} small; + +typedef struct { + long a; + long b; + long c; + long d; + long e; + long f; + long g; + long h; +} large; + +int exotic_arguments_struct_small(small a, int nonce) { + return a.a + a.b + nonce; +} + +long exotic_arguments_struct_large(large a, int nonce) { + return a.a + a.b + a.c + a.d + a.e + a.f + a.g + a.h + nonce; +} + +float exotic_arguments_float(float a, int nonce) { + return a + (float) nonce; +} + +double exotic_arguments_double(double a, int nonce) { + return a + (double) nonce; +} diff --git a/bench/fibonacci.c b/bench/fibonacci.c new file mode 100644 index 0000000..0acbffc --- /dev/null +++ b/bench/fibonacci.c @@ -0,0 +1,20 @@ +int fibonacci_loop(int n, int nonce) { + int x = nonce; + int y = nonce; + + for (int i = 1; i < n; ++i) { + int newy = x + y; + x = y; + y = newy; + } + + return y; +} + +int fibonacci_recursive(int n, int nonce) { + if (n < 2) { + return nonce; + } + + return fibonacci_recursive(n - 1, nonce) + fibonacci_recursive(n - 2, nonce); +} diff --git a/bench/two_dimension_array.c b/bench/two_dimension_array.c new file mode 100644 index 0000000..a58cee8 --- /dev/null +++ b/bench/two_dimension_array.c @@ -0,0 +1,24 @@ +int two_dimension_array_arr[100]; + +int two_dimension_array(int n, int nonce) { + if (!(n <= 100)) { + return nonce; + } + + for (int i = 0; i < n; ++i) { + two_dimension_array_arr[i] = i + nonce; + } + + for (int i = 0; i < n; ++i) { + for (int j = 0; i < n; ++i) { + two_dimension_array_arr[i] += two_dimension_array_arr[j]; + } + } + + int result = 0; + for (int i = 0; i < n; ++i) { + result += two_dimension_array_arr[i]; + } + + return result; +}