diff --git a/.gitignore b/.gitignore index ea86824..a55d6a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /hw*.zip +/final.zip **/*.rs.bk diff --git a/bench/.gitignore b/bench/.gitignore index e71133f..faa9788 100644 --- a/bench/.gitignore +++ b/bench/.gitignore @@ -1,3 +1,4 @@ -/.depend /bench +/bench-gcc *.o +*.s diff --git a/bench/Makefile b/bench/Makefile index 58e497f..d707aec 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -6,8 +6,9 @@ RM=rm -f SRCS=$(shell find . -name "*.c") OBJS=$(subst .c,.s,$(SRCS)) +OBJS_GCC=$(subst .c,.o,$(SRCS)) -all: bench +all: bench bench-gcc bench: $(OBJS) driver.o $(CXX) -o bench $(OBJS) driver.o @@ -15,14 +16,23 @@ bench: $(OBJS) driver.o run: bench qemu-riscv64-static -L /usr/riscv64-linux-gnu ./bench -driver.o: driver.cpp +bench-gcc: $(OBJS_GCC) driver.o + $(CXX) -o bench-gcc $(OBJS_GCC) driver.o + +run-gcc: bench-gcc + qemu-riscv64-static -L /usr/riscv64-linux-gnu ./bench-gcc + +driver.o: $(SRCS) driver.cpp $(CXX) $(CFLAGS) -o driver.o -c -I. driver.cpp -.c.s: +.c.s: $(KECC) ($(KECC) -O $< >$@) || (rm $@ -rf; exit 1) +.c.o: + ($(CC) -O -c $< -o $@) || (rm $@ -rf; exit 1) + $(KECC): cargo build --manifest-path=../Cargo.toml --release --bin kecc clean: - $(RM) $(OBJS) driver.o bench + $(RM) $(OBJS) $(OBJS_GCC) driver.o bench bench-gcc diff --git a/bench/driver.cpp b/bench/driver.cpp index ad8a96d..541de6e 100644 --- a/bench/driver.cpp +++ b/bench/driver.cpp @@ -10,16 +10,24 @@ namespace model { #include #include #include + #include + #include } extern "C" { int exotic_arguments_struct_small(model::small, int); long exotic_arguments_struct_large(model::large, int); + float exotic_arguments_struct_small_ugly(model::small_ugly, int); + double exotic_arguments_struct_large_ugly(model::large_ugly, 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); + int matrix_mul(int, int); + int matrix_add(int, int); + int graph_dijkstra(int, int); + int graph_floyd_warshall(int, int); } namespace { @@ -54,21 +62,32 @@ namespace { int main() { std::srand(static_cast(time(NULL))); + // Checks if the compiler observes the calling convention. + evaluate("exotic_arguments_struct_small", model::small { .a = 3, .b = 4 }, exotic_arguments_struct_small, model::exotic_arguments_struct_small); + 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); + evaluate("exotic_arguments_struct_small_ugly", model::small_ugly { .a = 5, .b = 6.0f }, exotic_arguments_struct_small_ugly, model::exotic_arguments_struct_small_ugly); + evaluate("exotic_arguments_struct_large_ugly", model::large_ugly { .a = 5, .b = 6.0f, .c = 7, .d = 8.0, .e = 9, .f = 10, .g = 11, .h = 12.0, .i = 13, .j = 14, .k = 15, .l = 16.0 }, exotic_arguments_struct_large_ugly, model::exotic_arguments_struct_large_ugly); + evaluate("exotic_arguments_float", 0.42f, exotic_arguments_float, model::exotic_arguments_float); + evaluate("exotic_arguments_double", 0.42, exotic_arguments_double, model::exotic_arguments_double); + + // Measures cycles for computationally heavy programs. 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); + for (int i = 0; i < 10; ++i) { + 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)); + cycles.push_back(evaluate("matrix_mul", 30, matrix_mul, model::matrix_mul)); + cycles.push_back(evaluate("matrix_add", 30, matrix_add, model::matrix_add)); + cycles.push_back(evaluate("graph_dijkstra", 1000, graph_dijkstra, model::graph_dijkstra)); + cycles.push_back(evaluate("graph_floyd_warshall", 200, graph_floyd_warshall, model::graph_floyd_warshall)); + } + + // Calculates the geometric mean. + auto average = 1.0; + auto factor = 1 / static_cast(cycles.size()); + for (auto cycle: cycles) { + average *= std::pow(static_cast(cycle), factor); } - 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 index 8007659..037df87 100644 --- a/bench/exotic_arguments.c +++ b/bench/exotic_arguments.c @@ -14,6 +14,26 @@ typedef struct { long h; } large; +typedef struct { + long a; + float b; +} small_ugly; + +typedef struct { + long a; + float b; + long c; + double d; + long e; + long f; + long g; + double h; + long i; + long j; + long k; + double l; +} large_ugly; + int exotic_arguments_struct_small(small a, int nonce) { return a.a + a.b + nonce; } @@ -22,6 +42,14 @@ 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_struct_small_ugly(small_ugly a, int nonce) { + return 0.0f + a.a + a.b + nonce; +} + +double exotic_arguments_struct_large_ugly(large_ugly a, int nonce) { + return 0.0 + 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; } diff --git a/bench/fibonacci.c b/bench/fibonacci.c index 0acbffc..78d0cb1 100644 --- a/bench/fibonacci.c +++ b/bench/fibonacci.c @@ -1,14 +1,30 @@ int fibonacci_loop(int n, int nonce) { - int x = nonce; - int y = nonce; + int result = 0; - for (int i = 1; i < n; ++i) { - int newy = x + y; - x = y; - y = newy; + for (int step = 0; step < 10; ++step) { + int x = nonce; + int y = nonce; + + for (int i = 1; i < n; ++i) { + int newy = x + y; + newy += (x + y); + newy += (x + y); + newy += (x + y); + newy += (x + y); + newy += (x + y); + newy -= (x + y); + newy -= (x + y); + newy -= (x + y); + newy -= (x + y); + newy -= (x + y); + x = y; + y = newy; + } + + result += y; } - return y; + return result; } int fibonacci_recursive(int n, int nonce) { diff --git a/bench/graph.c b/bench/graph.c new file mode 100644 index 0000000..7e48574 --- /dev/null +++ b/bench/graph.c @@ -0,0 +1,97 @@ +int graph_weight[1000][1000]; +int graph_dijkstra_dist[1000]; +int graph_dijkstra_visited[1000]; + +void graph_weight_init(int n, int nonce, int *x, int (*weight)[1000]) { + for (int i = 0; i < n; ++i) { + weight[i][i] = 0; + + for (int j = 1; j < n; ++j) { + weight[i][(i + j) % n] = ++*x; + + if (*x % (nonce + 1)) { + ++*x; + } + } + } +} + +int graph_dijkstra(int n, int nonce) { + if (!(n <= 1000)) { + return nonce; + } + + int x = 0; + graph_weight_init(n, nonce, &x, graph_weight); + + for (int i = 0; i < n; ++i) { + graph_dijkstra_dist[i] = -1; + graph_dijkstra_visited[i] = 0; + } + graph_dijkstra_dist[0] = 0; + + for (int step = 0; step < n; ++step) { + int v = -1; + for (int i = 0; i < n; ++i) { + if (!(graph_dijkstra_dist[i] != -1 && !graph_dijkstra_visited[i])) { + continue; + } + + if (v != -1 && graph_dijkstra_dist[v] < graph_dijkstra_dist[i]) { + continue; + } + + v = i; + } + + if (v == -1) { + break; + } + + int dist = graph_dijkstra_dist[v]; + graph_dijkstra_visited[v] = 1; + + for (int i = 0; i < n; ++i) { + if (graph_dijkstra_visited[i]) continue; + if (graph_dijkstra_dist[i] != -1 && graph_dijkstra_dist[i] < dist + graph_weight[v][i]) continue; + graph_dijkstra_dist[i] = dist + graph_weight[v][i]; + } + } + + int result = 0; + for (int i = 0; i < n; ++i) { + result += graph_dijkstra_dist[i]; + } + + return result; +} + +int graph_floyd_warshall(int n, int nonce) { + if (!(n <= 1000)) { + return nonce; + } + + int x = 0; + graph_weight_init(n, nonce, &x, graph_weight); + + for (int k = 0; k < n; ++k) { + for (int i = 0; i < n; ++i) { + if (graph_weight[i][k] == -1) continue; + + for (int j = 0; j < n; ++j) { + if (graph_weight[k][j] == -1) continue; + int weight = graph_weight[i][k] + graph_weight[k][j]; + if (graph_weight[i][j] != -1 && graph_weight[i][j] < weight) continue; + graph_weight[i][j] = weight; + } + } + } + + int result = 0; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + result += graph_weight[i][j]; + } + } + return result; +} diff --git a/bench/matrix.c b/bench/matrix.c new file mode 100644 index 0000000..2d2a183 --- /dev/null +++ b/bench/matrix.c @@ -0,0 +1,58 @@ +int matrix_a[30][30]; +int matrix_b[30][30]; +int matrix_c[30][30]; + +void matrix_init(int n, int nonce, int *x, int (*matrix)[30]) { + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + matrix[i][j] = ++*x; + + if (*x % (nonce + 1)) { + ++*x; + } + } + } +} + +int matrix_mul(int n, int nonce) { + if (!(n <= 30)) { + return nonce; + } + + int x = 0; + matrix_init(n, nonce, &x, matrix_a); + matrix_init(n, nonce, &x, matrix_b); + + int result = 0; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + matrix_c[i][j] = 0; + for (int k = 0; k < n; ++k) { + matrix_c[i][j] += matrix_a[i][k] * matrix_b[k][j]; + } + result += matrix_c[i][j]; + } + } + + return result; +} + +int matrix_add(int n, int nonce) { + if (!(n <= 30)) { + return nonce; + } + + int x = 0; + matrix_init(n, nonce, &x, matrix_a); + matrix_init(n, nonce, &x, matrix_b); + + int result = 0; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + matrix_c[i][j] = matrix_a[i][j] + nonce * matrix_b[i][j]; + result += matrix_c[i][j]; + } + } + + return result; +} diff --git a/scripts/make-submissions.sh b/scripts/make-submissions.sh index 3ed842f..e540328 100755 --- a/scripts/make-submissions.sh +++ b/scripts/make-submissions.sh @@ -5,3 +5,4 @@ zip hw3.zip -j src/opt/opt_utils.rs src/opt/simplify_cfg.rs zip hw4.zip -j src/opt/opt_utils.rs src/opt/mem2reg.rs zip hw5.zip -j src/opt/opt_utils.rs src/opt/gvn.rs zip hw6.zip -j src/opt/opt_utils.rs src/opt/deadcode.rs +zip final.zip -r src/