⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sim-profile.c

📁 gdb-6.0 linux 下的调试工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	  if (PROFILE_READ_COUNT (data) [i] != 0)	    {	      sim_io_printf (sd, "   %*s read:  %*s: ",			     max_name_len, MODE_NAME (i),			     max_val < 10000 ? 5 : 10,			     COMMAS (PROFILE_READ_COUNT (data) [i]));	      sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,				     PROFILE_READ_COUNT (data) [i],				     max_val);	      sim_io_printf (sd, "\n");	    }	  if (PROFILE_WRITE_COUNT (data) [i] != 0)	    {	      sim_io_printf (sd, "   %*s write: %*s: ",			     max_name_len, MODE_NAME (i),			     max_val < 10000 ? 5 : 10,			     COMMAS (PROFILE_WRITE_COUNT (data) [i]));	      sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,				     PROFILE_WRITE_COUNT (data) [i],				     max_val);	      sim_io_printf (sd, "\n");	    }	}    }  sim_io_printf (sd, "\n");}#endif#if WITH_PROFILE_CORE_Pstatic voidprofile_print_core (sim_cpu *cpu, int verbose){  unsigned int total;  unsigned int max_val;  /* FIXME: Need to add smp support.  */  SIM_DESC sd = CPU_STATE (cpu);  PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);  char comma_buf[20];  sim_io_printf (sd, "CORE Statistics\n\n");  /* First pass over data computes various things.  */  {    unsigned map;    total = 0;    max_val = 0;    for (map = 0; map < nr_maps; map++)      {	total += PROFILE_CORE_COUNT (data) [map];	if (PROFILE_CORE_COUNT (data) [map] > max_val)	  max_val = PROFILE_CORE_COUNT (data) [map];      }  }  /* One could use PROFILE_LABEL_WIDTH here.  I chose not to.  */  sim_io_printf (sd, "  Total:  %s accesses\n",		 COMMAS (total));  if (verbose && max_val != 0)    {      unsigned map;      /* Now we can print the histogram.  */      sim_io_printf (sd, "\n");      for (map = 0; map < nr_maps; map++)	{	  if (PROFILE_CORE_COUNT (data) [map] != 0)	    {	      sim_io_printf (sd, "%10s:", map_to_str (map));	      sim_io_printf (sd, "%*s: ",			     max_val < 10000 ? 5 : 10,			     COMMAS (PROFILE_CORE_COUNT (data) [map]));	      sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,				     PROFILE_CORE_COUNT (data) [map],				     max_val);	      sim_io_printf (sd, "\n");	    }	}    }  sim_io_printf (sd, "\n");}#endif#if WITH_PROFILE_MODEL_Pstatic voidprofile_print_model (sim_cpu *cpu, int verbose){  SIM_DESC sd = CPU_STATE (cpu);  PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);  unsigned long cti_stall_cycles = PROFILE_MODEL_CTI_STALL_CYCLES (data);  unsigned long load_stall_cycles = PROFILE_MODEL_LOAD_STALL_CYCLES (data);  unsigned long total_cycles = PROFILE_MODEL_TOTAL_CYCLES (data);  char comma_buf[20];  sim_io_printf (sd, "Model %s Timing Information",		 MODEL_NAME (CPU_MODEL (cpu)));#ifdef SIM_HAVE_ADDR_RANGE  if (PROFILE_RANGE (data)->ranges)    sim_io_printf (sd, " (for selected address range(s))");#endif  sim_io_printf (sd, "\n\n");  sim_io_printf (sd, "  %-*s %s\n",		 PROFILE_LABEL_WIDTH, "Taken branches:",		 COMMAS (PROFILE_MODEL_TAKEN_COUNT (data)));  sim_io_printf (sd, "  %-*s %s\n",		 PROFILE_LABEL_WIDTH, "Untaken branches:",		 COMMAS (PROFILE_MODEL_UNTAKEN_COUNT (data)));  sim_io_printf (sd, "  %-*s %s\n",		 PROFILE_LABEL_WIDTH, "Cycles stalled due to branches:",		 COMMAS (cti_stall_cycles));  sim_io_printf (sd, "  %-*s %s\n",		 PROFILE_LABEL_WIDTH, "Cycles stalled due to loads:",		 COMMAS (load_stall_cycles));  sim_io_printf (sd, "  %-*s %s\n",		 PROFILE_LABEL_WIDTH, "Total cycles (*approximate*):",		 COMMAS (total_cycles));  sim_io_printf (sd, "\n");}#endifvoidsim_profile_print_bar (SIM_DESC sd, unsigned int width,		       unsigned int val, unsigned int max_val){  unsigned int i, count;  count = ((double) val / (double) max_val) * (double) width;  for (i = 0; i < count; ++i)    sim_io_printf (sd, "*");}/* Print the simulator's execution speed for CPU.  */static voidprofile_print_speed (sim_cpu *cpu){  SIM_DESC sd = CPU_STATE (cpu);  PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);  unsigned long milliseconds = sim_events_elapsed_time (sd);  unsigned long total = PROFILE_TOTAL_INSN_COUNT (data);  double clock;  double secs;  char comma_buf[20];  sim_io_printf (sd, "Simulator Execution Speed\n\n");  if (total != 0)    sim_io_printf (sd, "  Total instructions:      %s\n", COMMAS (total));  if (milliseconds < 1000)    sim_io_printf (sd, "  Total execution time:    < 1 second\n\n");  else    {      /* The printing of the time rounded to 2 decimal places makes the speed	 calculation seem incorrect [even though it is correct].  So round	 MILLISECONDS first. This can marginally affect the result, but it's	 better that the user not perceive there's a math error.  */      secs = (double) milliseconds / 1000;      secs = ((double) (unsigned long) (secs * 100 + .5)) / 100;      sim_io_printf (sd, "  Total execution time   : %.2f seconds\n", secs);      /* Don't confuse things with data that isn't useful.	 If we ran for less than 2 seconds, only use the data if we	 executed more than 100,000 insns.  */      if (secs >= 2 || total >= 100000)	sim_io_printf (sd, "  Simulator speed:         %s insns/second\n",		       COMMAS ((unsigned long) ((double) total / secs)));    }  /* Print simulated execution time if the cpu frequency has been specified.  */  clock = PROFILE_CPU_FREQ (data);  if (clock != 0)    {      if (clock >= 1000000)	sim_io_printf (sd, "  Simulated cpu frequency: %.2f MHz\n",		       clock / 1000000);      else	sim_io_printf (sd, "  Simulated cpu frequency: %.2f Hz\n", clock);#if WITH_PROFILE_MODEL_P      if (PROFILE_FLAGS (data) [PROFILE_MODEL_IDX])	{	  /* The printing of the time rounded to 2 decimal places makes the	     speed calculation seem incorrect [even though it is correct].	     So round 	 SECS first. This can marginally affect the result,	     but it's 	 better that the user not perceive there's a math	     error.  */	  secs = PROFILE_MODEL_TOTAL_CYCLES (data) / clock;	  secs = ((double) (unsigned long) (secs * 100 + .5)) / 100;	  sim_io_printf (sd, "  Simulated execution time: %.2f seconds\n",			 secs);	}#endif /* WITH_PROFILE_MODEL_P */    }}/* Print selected address ranges.  */static voidprofile_print_addr_ranges (sim_cpu *cpu){  ADDR_SUBRANGE *asr = PROFILE_RANGE (CPU_PROFILE_DATA (cpu))->ranges;  SIM_DESC sd = CPU_STATE (cpu);  if (asr)    {      sim_io_printf (sd, "Selected address ranges\n\n");      while (asr != NULL)	{	  sim_io_printf (sd, "  0x%lx - 0x%lx\n",			 (long) asr->start, (long) asr->end);	  asr = asr->next;	}      sim_io_printf (sd, "\n");    }}/* Top level function to print all summary profile information.   It is [currently] intended that all such data is printed by this function.   I'd rather keep it all in one place for now.  To that end, MISC_CPU and   MISC are callbacks used to print any miscellaneous data.   One might want to add a user option that allows printing by type or by cpu   (i.e. print all insn data for each cpu first, or print data cpu by cpu).   This may be a case of featuritis so it's currently left out.   Note that results are indented two spaces to distinguish them from   section titles.  */static voidprofile_info (SIM_DESC sd, int verbose){  int i,c;  int print_title_p = 0;  /* Only print the title if some data has been collected.  */  /* ??? Why don't we just exit if no data collected?  */  /* FIXME: If the number of processors can be selected on the command line,     then MAX_NR_PROCESSORS will need to take an argument of `sd'.  */  for (c = 0; c < MAX_NR_PROCESSORS; ++c)    {      sim_cpu *cpu = STATE_CPU (sd, c);      PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);      for (i = 0; i < MAX_PROFILE_VALUES; ++i)	if (PROFILE_FLAGS (data) [i])	  print_title_p = 1;      /* One could break out early if print_title_p is set.  */    }  if (print_title_p)    sim_io_printf (sd, "Summary profiling results:\n\n");  /* Loop, cpu by cpu, printing results.  */  for (c = 0; c < MAX_NR_PROCESSORS; ++c)    {      sim_cpu *cpu = STATE_CPU (sd, c);      PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);      if (MAX_NR_PROCESSORS > 1	  && (0#if WITH_PROFILE_INSN_P	      || PROFILE_FLAGS (data) [PROFILE_INSN_IDX]#endif#if WITH_PROFILE_MEMORY_P	      || PROFILE_FLAGS (data) [PROFILE_MEMORY_IDX]#endif#if WITH_PROFILE_CORE_P	      || PROFILE_FLAGS (data) [PROFILE_CORE_IDX]#endif#if WITH_PROFILE_MODEL_P	      || PROFILE_FLAGS (data) [PROFILE_MODEL_IDX]#endif#if WITH_PROFILE_SCACHE_P && WITH_SCACHE	      || PROFILE_FLAGS (data) [PROFILE_SCACHE_IDX]#endif#if WITH_PROFILE_PC_P	      || PROFILE_FLAGS (data) [PROFILE_PC_IDX]#endif	      ))	{	  sim_io_printf (sd, "CPU %d\n\n", c);	}#ifdef SIM_HAVE_ADDR_RANGE      if (print_title_p	  && (PROFILE_INSN_P (cpu)	      || PROFILE_MODEL_P (cpu)))	profile_print_addr_ranges (cpu);#endif#if WITH_PROFILE_INSN_P      if (PROFILE_FLAGS (data) [PROFILE_INSN_IDX])	profile_print_insn (cpu, verbose);#endif#if WITH_PROFILE_MEMORY_P      if (PROFILE_FLAGS (data) [PROFILE_MEMORY_IDX])	profile_print_memory (cpu, verbose);#endif#if WITH_PROFILE_CORE_P      if (PROFILE_FLAGS (data) [PROFILE_CORE_IDX])	profile_print_core (cpu, verbose);#endif#if WITH_PROFILE_MODEL_P      if (PROFILE_FLAGS (data) [PROFILE_MODEL_IDX])	profile_print_model (cpu, verbose);#endif#if WITH_PROFILE_SCACHE_P && WITH_SCACHE      if (PROFILE_FLAGS (data) [PROFILE_SCACHE_IDX])	scache_print_profile (cpu, verbose);#endif#if WITH_PROFILE_PC_P      if (PROFILE_FLAGS (data) [PROFILE_PC_IDX])	profile_print_pc (cpu, verbose);#endif      /* Print cpu-specific data before the execution speed.  */      if (PROFILE_INFO_CPU_CALLBACK (data) != NULL)	PROFILE_INFO_CPU_CALLBACK (data) (cpu, verbose);      /* Always try to print execution time and speed.  */      if (verbose	  || PROFILE_FLAGS (data) [PROFILE_INSN_IDX])	profile_print_speed (cpu);    }  /* Finally print non-cpu specific miscellaneous data.  */  if (STATE_PROFILE_INFO_CALLBACK (sd))    STATE_PROFILE_INFO_CALLBACK (sd) (sd, verbose);}/* Install profiling support in the simulator.  */SIM_RCprofile_install (SIM_DESC sd){  int i;  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);  sim_add_option_table (sd, NULL, profile_options);  for (i = 0; i < MAX_NR_PROCESSORS; ++i)    memset (CPU_PROFILE_DATA (STATE_CPU (sd, i)), 0,	    sizeof (* CPU_PROFILE_DATA (STATE_CPU (sd, i))));#if WITH_PROFILE_INSN_P  sim_module_add_init_fn (sd, profile_insn_init);#endif#if WITH_PROFILE_PC_P  sim_module_add_uninstall_fn (sd, profile_pc_uninstall);  sim_module_add_init_fn (sd, profile_pc_init);#endif  sim_module_add_init_fn (sd, profile_init);  sim_module_add_uninstall_fn (sd, profile_uninstall);  sim_module_add_info_fn (sd, profile_info);  return SIM_RC_OK;}static SIM_RCprofile_init (SIM_DESC sd){#ifdef SIM_HAVE_ADDR_RANGE  /* Check if a range has been specified without specifying what to     collect.  */  {    int i;    for (i = 0; i < MAX_NR_PROCESSORS; ++i)      {	sim_cpu *cpu = STATE_CPU (sd, i);	if (ADDR_RANGE_RANGES (PROFILE_RANGE (CPU_PROFILE_DATA (cpu)))	    && ! (PROFILE_INSN_P (cpu)		  || PROFILE_MODEL_P (cpu)))	  {	    sim_io_eprintf_cpu (cpu, "Profiling address range specified without --profile-insn or --profile-model.\n");	    sim_io_eprintf_cpu (cpu, "Address range ignored.\n");	    sim_addr_range_delete (PROFILE_RANGE (CPU_PROFILE_DATA (cpu)),				   0, ~ (address_word) 0);	  }      }  }#endif  return SIM_RC_OK;}static voidprofile_uninstall (SIM_DESC sd){  int i,j;  for (i = 0; i < MAX_NR_PROCESSORS; ++i)    {      sim_cpu *cpu = STATE_CPU (sd, i);      PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);      if (PROFILE_FILE (data) != NULL)	{	  /* If output from different cpus is going to the same file,	     avoid closing the file twice.  */	  for (j = 0; j < i; ++j)	    if (PROFILE_FILE (CPU_PROFILE_DATA (STATE_CPU (sd, j)))		== PROFILE_FILE (data))	      break;	  if (i == j)	    fclose (PROFILE_FILE (data));	}      if (PROFILE_INSN_COUNT (data) != NULL)	zfree (PROFILE_INSN_COUNT (data));    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -