summaryrefslogtreecommitdiff
path: root/schulung_tools/matrix
diff options
context:
space:
mode:
Diffstat (limited to 'schulung_tools/matrix')
-rw-r--r--schulung_tools/matrix/Makefile12
-rw-r--r--schulung_tools/matrix/README7
-rw-r--r--schulung_tools/matrix/main.c91
3 files changed, 110 insertions, 0 deletions
diff --git a/schulung_tools/matrix/Makefile b/schulung_tools/matrix/Makefile
new file mode 100644
index 0000000..a5c8404
--- /dev/null
+++ b/schulung_tools/matrix/Makefile
@@ -0,0 +1,12 @@
+CFLAGS=-O0 -g -Wall -pedantic -lpthread -std=gnu99
+LDFLAGS=-lpthread
+
+all: main
+
+main.o: main.c
+main: main.o
+
+clean:
+ rm -rf main *.o
+
+.PHONY: clean
diff --git a/schulung_tools/matrix/README b/schulung_tools/matrix/README
new file mode 100644
index 0000000..40a1e75
--- /dev/null
+++ b/schulung_tools/matrix/README
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# investigate good cache usage
+sudo perf stat ./main -1
+
+# investigate bad cache usage
+sudo perf stat ./main -2
diff --git a/schulung_tools/matrix/main.c b/schulung_tools/matrix/main.c
new file mode 100644
index 0000000..9a6f2fa
--- /dev/null
+++ b/schulung_tools/matrix/main.c
@@ -0,0 +1,91 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <errno.h>
+
+/* matrix dimension */
+static size_t dim;
+
+/* options */
+static struct option long_opts[] = {
+ { "dim", required_argument, NULL, 'd' },
+ { "1", no_argument, NULL, '1' },
+ { "2", no_argument, NULL, '2' },
+ { NULL, 0, NULL, 0 },
+};
+
+static int visit_every_element_1(const int *matrix, size_t dim)
+{
+ int sum = 0;
+
+ /* row by row */
+ for (int i = 0; i < dim; ++i) {
+ for (int j = 0; j < dim; ++j) {
+ sum += matrix[i * dim + j];
+ }
+ }
+
+ return sum;
+}
+
+static int visit_every_element_2(const int *matrix, size_t dim)
+{
+ int sum = 0;
+
+ /* column by column */
+ for (int j = 0; j < dim; ++j) {
+ for (int i = 0; i < dim; ++i) {
+ sum += matrix[i * dim + j];
+ }
+ }
+
+ return sum;
+}
+
+static inline void print_usage_and_die(void)
+{
+ fprintf(stderr, "usage: matrix [-1|-2] [-d <size>]\n");
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+ int *matrix, sum;
+ char *end;
+ int c, choice = 1;
+
+ dim = 10000;
+ while ((c = getopt_long(argc, argv, "d:12", long_opts, NULL)) != -1) {
+ switch (c) {
+ case 'd':
+ dim = strtoull(optarg, &end, 10);
+ if (end == optarg || *end != '\0' || errno == ERANGE) {
+ fprintf(stderr, "given dim is not valid\n");
+ return EXIT_FAILURE;
+ }
+ break;
+ case '1':
+ choice = 1;
+ break;
+ case '2':
+ choice = 2;
+ break;
+ default:
+ print_usage_and_die();
+ }
+ }
+
+ matrix = (int *)calloc(dim * dim, sizeof(int));
+ if (!matrix) {
+ perror("malloc() failed");
+ return EXIT_FAILURE;
+ }
+
+ sum = choice == 1 ? visit_every_element_1(matrix, dim) :
+ visit_every_element_2(matrix, dim);
+ printf("Bogus result: %d\n", sum);
+
+ return EXIT_SUCCESS;
+}