1/* stats.c -*-C-*- 2 * 3 ************************************************************************* 4 * 5 * @copyright 6 * Copyright (C) 2009-2013, Intel Corporation 7 * All rights reserved. 8 * 9 * @copyright 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * * Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * * Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * * Neither the name of Intel Corporation nor the names of its 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. 23 * 24 * @copyright 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 32 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 33 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 35 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 **************************************************************************/ 38 39#include "stats.h" 40#include "bug.h" 41#include "os.h" 42#include "local_state.h" 43 44#include <stdio.h> 45 46#define INVALID_START (0ULL - 1ULL) 47 48#ifdef CILK_PROFILE 49/* MSVC does not support designated initializers, grrrr... */ 50static const char *names[] = { 51 /*[INTERVAL_IN_SCHEDULER]*/ "in scheduler", 52 /*[INTERVAL_WORKING]*/ " of which: working", 53 /*[INTERVAL_IN_RUNTIME]*/ " of which: in runtime", 54 /*[INTERVAL_STEALING]*/ " of which: stealing", 55 /*[INTERVAL_STEAL_SUCCESS]*/ "steal success: detach", 56 /*[INTERVAL_STEAL_FAIL_EMPTYQ]*/ "steal fail: empty queue", 57 /*[INTERVAL_STEAL_FAIL_LOCK]*/ "steal fail: victim locked", 58 /*[INTERVAL_STEAL_FAIL_USER_WORKER]*/ "steal fail: user worker", 59 /*[INTERVAL_STEAL_FAIL_DEKKER]*/ "steal fail: dekker", 60 /*[INTERVAL_SYNC_CHECK]*/ "sync check", 61 /*[INTERVAL_THE_EXCEPTION_CHECK]*/ "THE exception check", 62 /*[INTERVAL_THE_EXCEPTION_CHECK_USELESS]*/ " of which: useless", 63 /*[INTERVAL_RETURNING]*/ "returning", 64 /*[INTERVAL_FINALIZE_CHILD]*/ "finalize child", 65 /*[INTERVAL_PROVABLY_GOOD_STEAL]*/ "provably good steal", 66 /*[INTERVAL_UNCONDITIONAL_STEAL]*/ "unconditional steal", 67 /*[INTERVAL_ALLOC_FULL_FRAME]*/ "alloc full frame", 68 /*[INTERVAL_FRAME_ALLOC_LARGE]*/ "large frame alloc", 69 /*[INTERVAL_FRAME_ALLOC]*/ "small frame alloc", 70 /*[INTERVAL_FRAME_ALLOC_GLOBAL]*/ " of which: to global pool", 71 /*[INTERVAL_FRAME_FREE_LARGE]*/ "large frame free", 72 /*[INTERVAL_FRAME_FREE]*/ "small frame free", 73 /*[INTERVAL_FRAME_FREE_GLOBAL]*/ " of which: to global pool", 74 /*[INTERVAL_MUTEX_LOCK]*/ "mutex lock", 75 /*[INTERVAL_MUTEX_LOCK_SPINNING]*/ " spinning", 76 /*[INTERVAL_MUTEX_LOCK_YIELDING]*/ " yielding", 77 /*[INTERVAL_MUTEX_TRYLOCK]*/ "mutex trylock", 78 /*[INTERVAL_FIBER_ALLOCATE]*/ "fiber_allocate", 79 /*[INTERVAL_FIBER_DEALLOCATE]*/ "fiber_deallocate", 80 /*[INTERVAL_FIBER_ALLOCATE_FROM_THREAD]*/ "fiber_allocate_from_thread", 81 /*[INTERVAL_FIBER_DEALLOCATE_FROM_THREAD]*/ "fiber_deallocate (thread)", 82 /*[INTERVAL_SUSPEND_RESUME_OTHER]*/ "fiber suspend self + resume", 83 /*[INTERVAL_DEALLOCATE_RESUME_OTHER]*/ "fiber deallocate self + resume", 84}; 85#endif 86 87void __cilkrts_init_stats(statistics *s) 88{ 89 int i; 90 for (i = 0; i < INTERVAL_N; ++i) { 91 s->start[i] = INVALID_START; 92 s->accum[i] = 0; 93 s->count[i] = 0; 94 } 95 96 s->stack_hwm = 0; 97} 98 99#ifdef CILK_PROFILE 100void __cilkrts_accum_stats(statistics *to, statistics *from) 101{ 102 int i; 103 104 for (i = 0; i < INTERVAL_N; ++i) { 105 to->accum[i] += from->accum[i]; 106 to->count[i] += from->count[i]; 107 from->accum[i] = 0; 108 from->count[i] = 0; 109 } 110 111 if (from->stack_hwm > to->stack_hwm) 112 to->stack_hwm = from->stack_hwm; 113 from->stack_hwm = 0; 114} 115 116void __cilkrts_note_interval(__cilkrts_worker *w, enum interval i) 117{ 118 if (w) { 119 statistics *s = w->l->stats; 120 CILK_ASSERT(s->start[i] == INVALID_START); 121 s->count[i]++; 122 } 123} 124 125void __cilkrts_start_interval(__cilkrts_worker *w, enum interval i) 126{ 127 if (w) { 128 statistics *s = w->l->stats; 129 CILK_ASSERT(s->start[i] == INVALID_START); 130 s->start[i] = __cilkrts_getticks(); 131 s->count[i]++; 132 } 133} 134 135void __cilkrts_stop_interval(__cilkrts_worker *w, enum interval i) 136{ 137 if (w) { 138 statistics *s = w->l->stats; 139 CILK_ASSERT(s->start[i] != INVALID_START); 140 s->accum[i] += __cilkrts_getticks() - s->start[i]; 141 s->start[i] = INVALID_START; 142 } 143} 144 145void dump_stats_to_file(FILE *stat_file, statistics *s) 146{ 147 int i; 148 fprintf(stat_file, "\nCILK PLUS RUNTIME SYSTEM STATISTICS:\n\n"); 149 150 fprintf(stat_file, 151 " %-32s: %15s %10s %12s %10s\n", 152 "event", 153 "count", 154 "ticks", 155 "ticks/count", 156 "%total" 157 ); 158 for (i = 0; i < INTERVAL_N; ++i) { 159 fprintf(stat_file, " %-32s: %15llu", names[i], s->count[i]); 160 if (s->accum[i]) { 161 fprintf(stat_file, " %10.3g %12.3g %10.2f", 162 (double)s->accum[i], 163 (double)s->accum[i] / (double)s->count[i], 164 100.0 * (double)s->accum[i] / 165 (double)s->accum[INTERVAL_IN_SCHEDULER]); 166 } 167 fprintf(stat_file, "\n"); 168 } 169} 170#endif // CILK_PROFILE 171 172/* End stats.c */ 173