Skip to content

Instantly share code, notes, and snippets.

@Hugobros3
Last active June 28, 2023 13:28
Show Gist options
  • Save Hugobros3/a536382bbef0420ecd276874793cf5d8 to your computer and use it in GitHub Desktop.
Save Hugobros3/a536382bbef0420ecd276874793cf5d8 to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
typedef int T;
T foo_local_array(T a, T b, T c, int i) {
const T abc[3] = { a, b, c};
return abc[i];
}
T foo_switch_case(T a, T b, T c, int i) {
switch (i) {
case 0: return a;
case 1: return b;
case 2: return c;
default: __builtin_unreachable();
}
}
T foo_if_else_ret(T a, T b, T c, int i) {
if (i == 0)
return a;
else if (i == 1)
return b;
return c;
}
T foo_select_nobr(T a, T b, T c, int i) {
return a + (i & 1) * (b - a) + (i > 1) * (c - a);
}
__attribute__((noinline)) long bench(int N, T* buf, int* indices, char* name, T (*fn)(T, T, T, int)) {
struct timespec ts;
timespec_get(&ts, TIME_UTC);
srand(ts.tv_nsec);
T acc = 0, j = 0;
for (int i = 0; i < N; i++) {
j = buf[3 * (N - i) - 1] % N;
//j = i;
acc += fn(buf[3 * j + 0], buf[3 * j + 1], buf[3 * j + 2], indices[j]);
}
struct timespec te;
timespec_get(&te, TIME_UTC);
long end_us = te.tv_sec * 1000000 + te.tv_nsec / 1000;
long start_us = ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
long delta = end_us - start_us;
printf("ran '%s' took %dus acc = %d \n", name, (int) (delta), acc);
return delta;
}
int main(int argc, char** argv) {
struct timespec tss;
timespec_get(&tss, TIME_UTC);
srand(tss.tv_nsec);
int N = 65536 * 16;
int R = 16;
T* buf = malloc(N * 3 * sizeof(T));
int* indices = malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
buf[i * 3 + 0] = rand();
buf[i * 3 + 1] = rand();
buf[i * 3 + 2] = rand();
indices[i] = rand() % 3;
}
long acc[4] = { 0 };
char* str[4] = { "foo_local_array", "foo_if_else_ret", "foo_switch_case", "foo_select_nobr" };
T (*fns[4])(T, T, T, int) = { foo_local_array, foo_if_else_ret, foo_switch_case, foo_select_nobr };
for (int r = 0; r < R; r++) {
for (int t = 0; t < sizeof(acc) / sizeof(acc[0]); t++)
acc[t] += bench(N, buf, indices, str[t], fns[t]);
}
printf("Final results (%d iterations):\n", R);
for (int t = 0; t < sizeof(acc) / sizeof(acc[0]); t++) {
printf("Test '%s', took %dus on average\n", str[t], acc[t] / R);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment