Last active
June 28, 2023 13:28
-
-
Save Hugobros3/a536382bbef0420ecd276874793cf5d8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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