📄 profile.c
字号:
FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *r = ps->idiv_busy; /* If the latency of the resource is greater than the current wait then update the current wait. */ if (r[in_resource] > ps->vliw_wait) { if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for integer division in slot I%d:", in_resource); } ps->vliw_wait = r[in_resource]; }}/* Check the availability of the given float division resource and update the number of cycles the current VLIW insn must wait until it is available.*/voidvliw_wait_for_fdiv_resource (SIM_CPU *cpu, INT in_resource){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *r = ps->fdiv_busy; /* If the latency of the resource is greater than the current wait then update the current wait. */ if (r[in_resource] > ps->vliw_wait) { if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for floating point division in slot F%d:", in_resource); } ps->vliw_wait = r[in_resource]; }}/* Check the availability of the given float square root resource and update the number of cycles the current VLIW insn must wait until it is available.*/voidvliw_wait_for_fsqrt_resource (SIM_CPU *cpu, INT in_resource){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *r = ps->fsqrt_busy; /* If the latency of the resource is greater than the current wait then update the current wait. */ if (r[in_resource] > ps->vliw_wait) { if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for square root in slot F%d:", in_resource); } ps->vliw_wait = r[in_resource]; }}/* Check the availability of the given float unit resource and update the number of cycles the current VLIW insn must wait until it is available.*/voidvliw_wait_for_float_resource (SIM_CPU *cpu, INT in_resource){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *r = ps->float_busy; /* If the latency of the resource is greater than the current wait then update the current wait. */ if (r[in_resource] > ps->vliw_wait) { if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for floating point unit in slot F%d:", in_resource); } ps->vliw_wait = r[in_resource]; }}/* Check the availability of the given media unit resource and update the number of cycles the current VLIW insn must wait until it is available.*/voidvliw_wait_for_media_resource (SIM_CPU *cpu, INT in_resource){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *r = ps->media_busy; /* If the latency of the resource is greater than the current wait then update the current wait. */ if (r[in_resource] > ps->vliw_wait) { if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for media unit in slot M%d:", in_resource); } ps->vliw_wait = r[in_resource]; }}/* Run the caches until all requests for the given register(s) are satisfied. */voidload_wait_for_GR (SIM_CPU *cpu, INT in_GR){ if (in_GR >= 0) { int wait = 0; while (load_pending_for_register (cpu, in_GR, 1/*words*/, REGTYPE_NONE)) { frv_model_advance_cycles (cpu, 1); ++wait; } if (wait) { FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); ps->vliw_wait += wait; ps->vliw_load_stall += wait; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for gr%d:", in_GR); } }}voidload_wait_for_FR (SIM_CPU *cpu, INT in_FR){ if (in_FR >= 0) { FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *fr; int wait = 0; while (load_pending_for_register (cpu, in_FR, 1/*words*/, REGTYPE_FR)) { frv_model_advance_cycles (cpu, 1); ++wait; } /* Post processing time may have been added to the register's latency after the loads were processed. Account for that too. */ fr = ps->fr_busy; if (fr[in_FR]) { wait += fr[in_FR]; frv_model_advance_cycles (cpu, fr[in_FR]); } /* Update the vliw_wait with the number of cycles we waited for the load and any post-processing. */ if (wait) { ps->vliw_wait += wait; ps->vliw_load_stall += wait; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for fr%d:", in_FR); } }}voidload_wait_for_GRdouble (SIM_CPU *cpu, INT in_GR){ if (in_GR >= 0) { int wait = 0; while (load_pending_for_register (cpu, in_GR, 2/*words*/, REGTYPE_NONE)) { frv_model_advance_cycles (cpu, 1); ++wait; } if (wait) { FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); ps->vliw_wait += wait; ps->vliw_load_stall += wait; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for gr%d:", in_GR); } }}voidload_wait_for_FRdouble (SIM_CPU *cpu, INT in_FR){ if (in_FR >= 0) { FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *fr; int wait = 0; while (load_pending_for_register (cpu, in_FR, 2/*words*/, REGTYPE_FR)) { frv_model_advance_cycles (cpu, 1); ++wait; } /* Post processing time may have been added to the registers' latencies after the loads were processed. Account for that too. */ fr = ps->fr_busy; if (fr[in_FR]) { wait += fr[in_FR]; frv_model_advance_cycles (cpu, fr[in_FR]); } if (in_FR < 63) { if (fr[in_FR + 1]) { wait += fr[in_FR + 1]; frv_model_advance_cycles (cpu, fr[in_FR + 1]); } } /* Update the vliw_wait with the number of cycles we waited for the load and any post-processing. */ if (wait) { ps->vliw_wait += wait; ps->vliw_load_stall += wait; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for fr%d:", in_FR); } }}voidenforce_full_fr_latency (SIM_CPU *cpu, INT in_FR){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); ps->fr_busy_adjust [in_FR] = -1;}/* Calculate how long the post processing for a floating point insn must wait for resources to become available. */intpost_wait_for_FR (SIM_CPU *cpu, INT in_FR){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *fr = ps->fr_busy; if (in_FR >= 0 && fr[in_FR] > ps->post_wait) { ps->post_wait = fr[in_FR]; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for fr%d:", in_FR); }}/* Calculate how long the post processing for a floating point insn must wait for resources to become available. */intpost_wait_for_FRdouble (SIM_CPU *cpu, INT in_FR){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *fr = ps->fr_busy; if (in_FR >= 0) { if (fr[in_FR] > ps->post_wait) { ps->post_wait = fr[in_FR]; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for fr%d:", in_FR); } if (in_FR < 63 && fr[in_FR + 1] > ps->post_wait) { ps->post_wait = fr[in_FR + 1]; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for fr%d:", in_FR + 1); } }}intpost_wait_for_ACC (SIM_CPU *cpu, INT in_ACC){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *acc = ps->acc_busy; if (in_ACC >= 0 && acc[in_ACC] > ps->post_wait) { ps->post_wait = acc[in_ACC]; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for acc%d:", in_ACC); }}intpost_wait_for_CCR (SIM_CPU *cpu, INT in_CCR){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *ccr = ps->ccr_busy; if (in_CCR >= 0 && ccr[in_CCR] > ps->post_wait) { ps->post_wait = ccr[in_CCR]; if (TRACE_INSN_P (cpu)) { if (in_CCR > 3) sprintf (hazard_name, "Data hazard for icc%d:", in_CCR - 4); else sprintf (hazard_name, "Data hazard for fcc%d:", in_CCR); } }}intpost_wait_for_SPR (SIM_CPU *cpu, INT in_SPR){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *spr = ps->spr_busy; if (in_SPR >= 0 && spr[in_SPR] > ps->post_wait) { ps->post_wait = spr[in_SPR]; if (TRACE_INSN_P (cpu)) sprintf (hazard_name, "Data hazard for spr[%d]:", in_SPR); }}intpost_wait_for_fdiv (SIM_CPU *cpu, INT slot){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *fdiv = ps->fdiv_busy; /* Multiple floating point divisions in the same slot need only wait 1 extra cycle. */ if (fdiv[slot] > 0 && 1 > ps->post_wait) { ps->post_wait = 1; if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for floating point division in slot F%d:", slot); } }}intpost_wait_for_fsqrt (SIM_CPU *cpu, INT slot){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *fsqrt = ps->fsqrt_busy; /* Multiple floating point square roots in the same slot need only wait 1 extra cycle. */ if (fsqrt[slot] > 0 && 1 > ps->post_wait) { ps->post_wait = 1; if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for square root in slot F%d:", slot); } }}intpost_wait_for_float (SIM_CPU *cpu, INT slot){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *flt = ps->float_busy; /* Multiple floating point square roots in the same slot need only wait 1 extra cycle. */ if (flt[slot] > ps->post_wait) { ps->post_wait = flt[slot]; if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for floating point unit in slot F%d:", slot); } }}intpost_wait_for_media (SIM_CPU *cpu, INT slot){ FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); int *media = ps->media_busy; /* Multiple floating point square roots in the same slot need only wait 1 extra cycle. */ if (media[slot] > ps->post_wait) { ps->post_wait = media[slot]; if (TRACE_INSN_P (cpu)) { sprintf (hazard_name, "Resource hazard for media unit in slot M%d:", slot); } }}/* Print cpu-specific profile information. */#define COMMAS(n) sim_add_commas (comma_buf, sizeof (comma_buf), (n))static voidprint_cache (SIM_CPU *cpu, FRV_CACHE *cache, const char *cache_name){ SIM_DESC sd = CPU_STATE (cpu); if (cache != NULL) { char comma_buf[20]; unsigned accesses; sim_io_printf (sd, " %s Cache\n\n", cache_name); accesses = cache->statistics.accesses; sim_io_printf (sd, " Total accesses: %s\n", COMMAS (accesses)); if (accesses != 0) { float rate; unsigned hits = cache->statistics.hits; sim_io_printf (sd, " Hits: %s\n", COMMAS (hits)); rate = (float)hits / accesses; sim_io_printf (sd, " Hit rate: %.2f%%\n", rate * 100); } } else sim_io_printf (sd, " Model %s has no %s cache\n", MODEL_NAME (CPU_MODEL (cpu)), cache_name); sim_io_printf (sd, "\n");}/* This table must correspond to the UNIT_ATTR table in opcodes/frv-desc.h. Only the units up to UNIT_C need be listed since the others cannot occur after mapping. */static char *slot_names[] ={ "none", "I0", "I1", "I01", "I2", "I3", "IALL", "FM0", "FM1", "FM01", "FM2", "FM3", "FMALL", "FMLOW", "B0", "B1", "B01", "C"};static voidprint_parallel (SIM_CPU *cpu, int verbose){ SIM_DESC sd = CPU_STATE (cpu); PROFILE_DATA *p = CPU_PROFILE_DATA (cpu); FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); unsigned total, vliw; char comma_buf[20]; float average; sim_io_printf (sd, "Model %s Parallelization\n\n", MODEL_NAME (CPU_MODEL (cpu))); total = PROFILE_TOTAL_INSN_COUNT (p); sim_io_printf (sd, " Total instructions: %s\n", COMMAS (total)); vliw = ps->vliw_insns; sim_io_printf (sd, " VLIW instructions: %s\n", COMMAS (vliw)); average = (float)total / vliw; sim_io_printf (sd, " Average VLIW length: %.2f\n", average); average = (float)PROFILE_MODEL_TOTAL_CYCLES (p) / vliw; sim_io_printf (sd, " Cycles per VLIW instruction: %.2f\n", average); average = (float)total / PROFILE_MODEL_TOTAL_CYCLES (p); sim_io_printf (sd, " Instructions per cycle: %.2f\n", average); if (verbose) { int i; int max_val = 0; int max_name_len = 0; for (i = UNIT_NIL + 1; i < UNIT_NUM_UNITS; ++i) { if (INSNS_IN_SLOT (i)) { int len; if (INSNS_IN_SLOT (i) > max_val) max_val = INSNS_IN_SLOT (i); len = strlen (slot_names[i]); if (len > max_name_len) max_name_len = len; } } if (max_val > 0) { sim_io_printf (sd, "\n"); sim_io_printf (sd, " Instructions per slot:\n"); sim_io_printf (sd, "\n"); for (i = UNIT_NIL + 1; i < UNIT_NUM_UNITS; ++i) { if (INSNS_IN_SLOT (i) != 0) { sim_io_printf (sd, " %*s: %*s: ", max_name_len, slot_names[i], max_val < 10000 ? 5 : 10, COMMAS (INSNS_IN_SLOT (i))); sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH, INSNS_IN_SLOT (i), max_val); sim_io_printf (sd, "\n"); } } } /* details to print */ } /* verbose */ sim_io_printf (sd, "\n");}voidfrv_profile_info (SIM_CPU *cpu, int verbose){ /* FIXME: Need to add smp support. */ PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);#if WITH_PROFILE_PARALLEL_P if (PROFILE_FLAGS (p) [PROFILE_PARALLEL_IDX]) print_parallel (cpu, verbose);#endif#if WITH_PROFILE_CACHE_P if (PROFILE_FLAGS (p) [PROFILE_CACHE_IDX]) { SIM_DESC sd = CPU_STATE (cpu); sim_io_printf (sd, "Model %s Cache Statistics\n\n", MODEL_NAME (CPU_MODEL (cpu))); print_cache (cpu, CPU_INSN_CACHE (cpu), "Instruction"); print_cache (cpu, CPU_DATA_CACHE (cpu), "Data"); }#endif /* WITH_PROFILE_CACHE_P */}/* A hack to get registers referenced for profiling. */SI frv_ref_SI (SI ref) {return ref;}#endif /* WITH_PROFILE_MODEL_P */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -