skcms→019d877 add a basic profiling mode to src/Transform.c

Change-Id: I136064f8b772f1aa5ecfedac4b0f9ebb92da9d73
Reviewed-on: https://skia-review.googlesource.com/121486
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
This commit is contained in:
Mike Klein 2018-04-16 11:10:08 -04:00
parent c8cdad7017
commit ef52250df9
3 changed files with 94 additions and 53 deletions

View File

@ -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;

View File

@ -9,57 +9,56 @@
#pragma once
#define FOREACH_Op(M) \
M(noop) \
M(load_565) \
M(load_888) \
M(load_8888) \
M(load_1010102) \
M(load_161616) \
M(load_16161616) \
M(load_hhh) \
M(load_hhhh) \
M(load_fff) \
M(load_ffff) \
M(swap_rb) \
M(clamp) \
M(invert) \
M(force_opaque) \
M(premul) \
M(unpremul) \
M(matrix_3x3) \
M(matrix_3x4) \
M(lab_to_xyz) \
M(tf_r) \
M(tf_g) \
M(tf_b) \
M(tf_a) \
M(table_8_r) \
M(table_8_g) \
M(table_8_b) \
M(table_8_a) \
M(table_16_r) \
M(table_16_g) \
M(table_16_b) \
M(table_16_a) \
M(clut_3D_8) \
M(clut_3D_16) \
M(clut_4D_8) \
M(clut_4D_16) \
M(store_565) \
M(store_888) \
M(store_8888) \
M(store_1010102) \
M(store_161616) \
M(store_16161616) \
M(store_hhh) \
M(store_hhhh) \
M(store_fff) \
M(store_ffff)
typedef enum {
Op_noop,
Op_load_565,
Op_load_888,
Op_load_8888,
Op_load_1010102,
Op_load_161616,
Op_load_16161616,
Op_load_hhh,
Op_load_hhhh,
Op_load_fff,
Op_load_ffff,
Op_swap_rb,
Op_clamp,
Op_invert,
Op_force_opaque,
Op_premul,
Op_unpremul,
Op_matrix_3x3,
Op_matrix_3x4,
Op_lab_to_xyz,
Op_tf_r,
Op_tf_g,
Op_tf_b,
Op_tf_a,
Op_table_8_r,
Op_table_8_g,
Op_table_8_b,
Op_table_8_a,
Op_table_16_r,
Op_table_16_g,
Op_table_16_b,
Op_table_16_a,
Op_clut_3D_8,
Op_clut_3D_16,
Op_clut_4D_8,
Op_clut_4D_16,
Op_store_565,
Op_store_888,
Op_store_8888,
Op_store_1010102,
Op_store_161616,
Op_store_16161616,
Op_store_hhh,
Op_store_hhhh,
Op_store_fff,
Op_store_ffff,
#define M(op) Op_##op,
FOREACH_Op(M)
#undef M
} Op;

View File

@ -570,7 +570,7 @@ static void NS(exec_ops)(const Op* ops, const void** args,
const char* src, char* dst, int i) {
F r = F0, g = F0, b = F0, a = F0;
while (true) {
switch (*ops++) {
switch (profile_next_op(*ops++)) {
case Op_noop: break;
case Op_load_565:{