void TraceCounter::endOverview() { DEBUGF(("%d/%d DEBUG: endOverview\n", CmiMyPe(), CmiNumPes())); double t = TraceTimer(); int _numEntries=_entryTable.size(); long long value1 = 0, value2 = 0; int genRead; if ((genRead=read_counters(counter1_->code, &value1, counter2_->code, &value2)) < 0 || genRead != genStart_) { CmiPrintf("genRead %d genStart_ %d counter1 %ld counter2 %ld\n", genRead, genStart_, value1, value2); traceClose(); CmiAbort("ERROR: read_counters() in endOverview\n"); } DEBUGF(( "%d/%d DEBUG: endOverview genRead %d Time %f counter1 %ld counter2 %ld\n", CmiMyPe(), CmiNumPes(), genRead, t-startEP_, value1, value2)); dirty_ = false; CpvAccess(_logPool)->setEp(_numEntries, counter1_->index, value1, counter2_->index, value2, t-startEP_); DEBUGF(( "%d/%d OVERVIEW phase%d Time(us) %f %s %ld %s %ld Idle(us) %f" " (overflow? MAX=%ld)\n", CmiMyPe(), CmiNumPes(), phase_, (t-startEP_)*1e6, counter1_->arg, value1, counter2_->arg, value2, idleTime_*1e6, MAXLONGLONG)); // this is phase boundary anyway, so switch counters switchCounters(); }
/******************************************************************************* * inst_schedule - Probe for schedule * @p - Not used * @regs - Not used * @return - always 0 * @Side Effects - Updates the tasks counters and requests a re-schedule * if the total executed instructions exceed INST_THRESHOLD * * Responsible for updating reading/writing the performance counters. * And also the one which decides when a task has executed enough *******************************************************************************/ int inst_schedule(struct kprobe *p, struct pt_regs *regs) { int cpu = smp_processor_id(); if (!ts[cpu] || TS_MEMBER(ts[cpu], seeker_scheduled) != SEEKER_MAGIC_NUMBER) return 0; if (is_blacklist_task(ts[cpu])) return 0; read_counters(cpu); if (TS_MEMBER(ts[cpu], interval) != interval_count) TS_MEMBER(ts[cpu], interval) = interval_count; TS_MEMBER(ts[cpu], inst) += pmu_val[cpu][0]; TS_MEMBER(ts[cpu], re_cy) += pmu_val[cpu][1]; TS_MEMBER(ts[cpu], ref_cy) += get_tsc_cycles(); clear_counters(cpu); if (TS_MEMBER(ts[cpu], inst) > INST_THRESHOLD || TS_MEMBER(ts[cpu], cpustate) != cur_cpu_state[cpu] || TS_MEMBER(ts[cpu], interval) != interval_count) { set_tsk_need_resched(ts[cpu]); /* lazy, as we are anyway getting into schedule */ } return 0; }
static void process_interval(void) { struct timespec ts, rs; read_counters(false); clock_gettime(CLOCK_MONOTONIC, &ts); diff_timespec(&rs, &ts, &ref_time); print_counters(&rs, 0, NULL); }
static void update_stats(struct sample *sample_c, char *iface, struct timespec deadline) { struct sample sample_o; struct timespec whoosh_err; /* the sound of a missed deadline. */ pthread_mutex_lock(&g_stats_mutex); /* FIXME: this smells funny */ memcpy(&sample_o, &g_stats_o, sizeof(struct sample)); if (0 == read_counters(iface, sample_c)) { clock_gettime(CLOCK_MONOTONIC, &(sample_c->timestamp)); whoosh_err = ts_absdiff(sample_c->timestamp, deadline); sample_c->whoosh_error_ns = whoosh_err.tv_nsec; calc_deltas(&sample_o, sample_c); } memcpy(&g_stats_o, sample_c, sizeof(struct sample)); pthread_mutex_unlock(&g_stats_mutex); }
//! begin/end execution of a Charm++ entry point //! NOTE: begin/endPack and begin/endUnpack can be called in between //! a beginExecute and its corresponding endExecute. void TraceCounter::endExecute() { DEBUGF(("%d/%d DEBUG: endExecute EP %d genStart_ %d\n", CmiMyPe(), CmiNumPes(), execEP_, genStart_)); if (!traceOn_ || overview_) { return; } if (status_!=WORKING) { static bool print = true; if (print) { print = false; if (CmiMyPe()==0) { CmiPrintf("WARN: %d endExecute called when status not WORKING!\n", CmiMyPe()); } } return; } else { status_=IDLE; } double t = TraceTimer(); long long value1 = 0, value2 = 0; int genRead; if ((genRead=read_counters(counter1_->code, &value1, counter2_->code, &value2)) < 0 || genRead != genStart_) { CmiPrintf("genRead %d genStart_ %d counter1 %ld counter2 %ld\n", genRead, genStart_, value1, value2); traceClose(); CmiAbort("ERROR: read_counters() in endExecute\n"); } DEBUGF(( "%d/%d DEBUG: endExecute genRead %d Time %f counter1 %d counter2 %ld\n", CmiMyPe(), CmiNumPes(), genRead, t-startEP_, value1, value2)); if (execEP_ != -1) { dirty_ = true; CpvAccess(_logPool)->setEp(execEP_, counter1_->index, value1, counter2_->index, value2, t-startEP_); if (!switchByPhase_) { switchCounters(); } } }
int main(void) { cpu_set_t cpus; int wr_cnt, wr_miss, drd_cnt, drd_miss; unsigned long start_cycles = get_cycle_count(); // Init cpus if (tmc_cpus_get_my_affinity(&cpus) != 0) { tmc_task_die("Failure in 'tmc_cpus_get_my_affinity()'."); } int num_cpus = tmc_cpus_count(&cpus); printf("cpus_count is: %i\n", num_cpus); // Setup Counters setup_all_counters(&cpus); unsigned long start_for = get_cycle_count(); unsigned long cycles[num_cpus]; unsigned int drd_cnts[num_cpus]; for (int i=0;i<num_cpus;i++) { if (tmc_cpus_set_my_cpu(tmc_cpus_find_nth_cpu(&cpus, i)) < 0) { tmc_task_die("failure in 'tmc_set_my_cpu'"); } read_counters(&wr_cnt, &wr_miss, &drd_cnt, &drd_miss); drd_cnts[i] = drd_cnt; cycles[i] = get_cycle_count(); } unsigned long end_for = get_cycle_count(); for (int i=1;i<num_cpus;i++) { unsigned long temp = cycles[i] - cycles[i-1]; printf("time between %i and %i is %lu\n", i-1, i, temp); printf("drd_cnt for tile %i was %i\n", i, drd_cnts[i]); } printf("Total cycles for-loop: %lu\n", end_for-start_for); return 0; }