diff options
Diffstat (limited to 'third_party/skcms/src/Transform.c')
-rw-r--r-- | third_party/skcms/src/Transform.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/third_party/skcms/src/Transform.c b/third_party/skcms/src/Transform.c index 7428ea6be4..b6b3e8e320 100644 --- a/third_party/skcms/src/Transform.c +++ b/third_party/skcms/src/Transform.c @@ -7,6 +7,7 @@ #include "../skcms.h" #include "LinearAlgebra.h" +#include "Macros.h" #include "PortableMath.h" #include "TransferFunction.h" #include "Transform.h" @@ -15,6 +16,47 @@ #include <stdint.h> #include <string.h> +#if defined(SKCMS_PROFILE) + // Basic profiling tools to time each Op. Not at all thread safe. + + #include <stdio.h> + #include <stdlib.h> + + #define M(op) +1 + static uint64_t cycles[FOREACH_Op(M)]; + #undef M + + static void profile_dump_stats() { + #define M(op) #op, + static const char* names[] = { FOREACH_Op(M) }; + #undef M + for (int i = 0; i < ARRAY_COUNT(cycles); i++) { + if (cycles[i]) { + fprintf(stderr, "%16s: %12llu cycles\n", names[i], cycles[i]); + } + } + } + + static Op profile_next_op(Op op) { + static uint64_t start = 0; + static uint64_t* current = NULL; + + if (!current) { + atexit(profile_dump_stats); + } else { + *current += __builtin_readcyclecounter() - start; + } + + current = &cycles[op]; + start = __builtin_readcyclecounter(); + return op; + } +#else + static inline Op profile_next_op(Op op) { + return op; + } +#endif + #if defined(__clang__) typedef float __attribute__((ext_vector_type(4))) Fx4; typedef int32_t __attribute__((ext_vector_type(4))) I32x4; |