diff --git a/aim-sort/Makefile b/aim-sort/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..89195153257195b95b406c0c4b5634519557acd4
--- /dev/null
+++ b/aim-sort/Makefile
@@ -0,0 +1,57 @@
+# Compilation settings:
+CFLAGS=-Wall -std=gnu99 $(MYCFLAGS)
+LDFLAGS=-lm $(MYLDFLAGS)
+
+OPTCFLAGS=$(CFLAGS) -O3 -march=native -DNDEBUG
+DBGCFLAGS=$(CFLAGS) -ggdb3
+
+# Benchmarking settings:
+RUNS=4
+ITERS=20
+
+
+######
+
+
+.PHONY: all clean benchmark evaluate asm
+all: aim-opt aim-dbg
+
+
+random: random.c
+	$(CC) $(OPTCFLAGS) -o $@ $^ $(LDFLAGS) 
+
+aim-opt: aim-run.c exercise.c
+	$(CC) $(OPTCFLAGS) -o $@ $^ $(LDFLAGS) 
+
+aim-dbg: aim-run.c exercise.c
+	$(CC) $(DBGCFLAGS) -o $@ $^ $(LDFLAGS)
+
+
+exercise-opt.s: exercise.c
+	$(CC) $(OPTCFLAGS) -fverbose-asm -S $< -o $@
+
+exercise-dbg.s: exercise.c
+	$(CC) $(DBGCFLAGS) -fverbose-asm -S $< -o $@
+
+asm: exercise-dbg.s exercise-opt.s
+
+
+clean:
+	rm -f *.o *.s aim-opt aim-dbg output.pbm random
+
+
+benchmark: aim-opt
+	@{ echo; \
+		top -b -n 5 | head -n 5; \
+		echo; \
+		echo '>>> Will compute time needed for $(ITERS) iterations averaged over $(RUNS) runs.'; \
+		echo '>>> The measured mean time, its probable lower and upper bounds and S.D.'; \
+		echo '>>> are printed out. See the header of statistics.awk for details.'; } >&2
+	@(for i in `seq 1 $(RUNS)`; do \
+		./aim-opt $(ITERS) test16384.pbm output.pbm | tee /dev/stderr; \
+	done) | awk -f statistics.awk
+
+evaluate: aim-opt
+	for s in 64 1024; do ./aim-opt 1 test$$s.pbm output.pbm; done >/dev/null
+	# Consider the optimistic estimate
+	make -s benchmark | { read m o p s; echo $$m $$o $$p $$s >&2; echo $$o; }
diff --git a/aim-sort/aim-run.c b/aim-sort/aim-run.c
new file mode 100644
index 0000000000000000000000000000000000000000..b50edfd206b0a2b60602bb7f3cb9aa68947b710e
--- /dev/null
+++ b/aim-sort/aim-run.c
@@ -0,0 +1,84 @@
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <assert.h>
+
+#include "aim.h"
+
+
+typedef int_fast64_t timestamp_t;
+
+static timestamp_t
+get_timer(void)
+{
+	struct timeval t;
+	gettimeofday(&t, NULL);
+	return 1000000*t.tv_sec + t.tv_usec;
+}
+
+int * seq_load(char *file, int * length) {
+	FILE *f = fopen(file, "r");
+	if (!f) {
+		printf("Could not read input file.\n");
+		exit(1);
+	}
+	char *line = NULL;
+	size_t ll = 0, i = 0;
+	int * seq = NULL;
+	while (getline(&line, &ll, f) != -1) {
+		if (seq == NULL) {
+			int l = atoi(line);
+			seq = malloc(sizeof(int)*l);
+			(*length) = l;
+		} else {
+			seq[i++] = atoi(line);
+		}
+	}
+	fclose(f);
+	assert(seq);
+	assert(i == (*length));
+	return seq;
+}
+
+void seq_store(char *file, int *seq, int length) {
+	FILE *f = fopen(file, "w");
+	fprintf(f, "%i\n", length);
+	assert(f);
+	for (int i = 0; i < length; i++) {
+		fprintf(f, "%i\n", seq[i]);
+	}
+	fclose(f);
+	return;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	if (argc != 4) {
+		fprintf(stderr, "%s ITERATIONS SRCSEQ.txt OUTSEQ.txt\n", argv[0]);
+		return EXIT_FAILURE;
+	}
+
+	int length;
+	int * seq = seq_load(argv[2], &length);
+	timestamp_t t0 = get_timer();
+
+	/* Pre-warm the CPU! Neccessary for benchmarking w/ dynamic
+	 * cpufreq policy. */
+	while (get_timer() - t0 < 500000);
+	t0 = get_timer();
+
+	int iters = atoi(argv[1]);
+	for (int j = 0; j < iters; j++) {
+		exercise(seq, length);
+	}
+
+	t0 = get_timer() - t0;
+	// time spent:
+	printf("%.3f\n", (double) t0/1e6);
+	seq_store(argv[3], seq, length);
+	return EXIT_SUCCESS;
+}
diff --git a/aim-sort/aim.h b/aim-sort/aim.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbefc9914335941b588e96cd9748712fad919547
--- /dev/null
+++ b/aim-sort/aim.h
@@ -0,0 +1,8 @@
+#ifndef AIM__AIM_H
+#define AIM__AIM_H
+
+#include <stdbool.h>
+
+void exercise(int * seq, size_t length);
+
+#endif
diff --git a/aim-sort/exercise.c b/aim-sort/exercise.c
new file mode 100644
index 0000000000000000000000000000000000000000..2abc36cf009c1559e786552db1bed5714ee8258b
--- /dev/null
+++ b/aim-sort/exercise.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "aim.h"
+#include <stdint.h>
+#include <math.h>
+#include <stdlib.h>
+
+static int qcomp(int *a, int *b) {
+	return (*a) - (*b);
+}
+
+void exercise(int * seq, size_t length) {
+	qsort(seq, length, sizeof(int), (__compar_fn_t) &qcomp);
+}
diff --git a/aim-sort/random.c b/aim-sort/random.c
new file mode 100644
index 0000000000000000000000000000000000000000..e4c0a50e335cf367671827b7eced22f71fe4eb03
--- /dev/null
+++ b/aim-sort/random.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+	if (argc != 2) { fprintf(stderr, "Usage: %s count\n", argv[0]); exit(1); }
+	int count = atoi(argv[1]);
+	if (count <= 0) {
+		fprintf(stderr, "Invalid count given: %i\n", count); 
+		exit(2);
+	}
+
+	printf("%i\n", count);
+	for (int i = 0; i < count; i++) {
+		printf("%i\n", rand());
+	}
+}
diff --git a/aim-sort/statistics.awk b/aim-sort/statistics.awk
new file mode 100644
index 0000000000000000000000000000000000000000..27719f6a7067956bda564eb2a317a52513ea9a90
--- /dev/null
+++ b/aim-sort/statistics.awk
@@ -0,0 +1,29 @@
+# We will compute the mean and standard deviation of the numbers on stdin.
+# We can interpret the standard deviation [*] like this:
+#
+# 	With probability 68%, the actual mean time M is within one S.D. s
+#	around the measured mean m: M \in (m-s,m+s)
+#
+# [*] We assume the numbers (time taken) are approximately normally
+# distributed around the measured mean.
+
+BEGIN {
+	sum = 0
+	sqsum = 0
+}
+
+{
+	sum = sum + $1
+	sqsum = sqsum + $1*$1
+}
+
+END {
+	n = NR
+	mean = sum / n
+	# Exercise: This method of variance computation might be
+	# sub-optimal. Try to find out why and implement a better
+	# method.
+	var = (n * sqsum - sum * sum) / (n * (n-1))
+	sd = sqrt(var)
+	print mean, mean - sd, mean + sd, sd
+}