aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/skcms/src/Transform.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/skcms/src/Transform.c')
-rw-r--r--third_party/skcms/src/Transform.c42
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;