profiling_helpers.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2011, 2013, 2016 Université de Bordeaux
  4. *
  5. * StarPU is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * StarPU is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #include <starpu.h>
  17. #include <starpu_profiling.h>
  18. #include <profiling/profiling.h>
  19. #include <datawizard/memory_nodes.h>
  20. static double convert_to_byte_units(float d, unsigned max_unit, unsigned *unit)
  21. {
  22. const double divisor = 1024;
  23. *unit = 0;
  24. while (d > divisor && *unit < max_unit)
  25. {
  26. d /= divisor;
  27. (*unit)++;
  28. }
  29. return d;
  30. }
  31. void _starpu_profiling_bus_helper_display_summary(FILE *stream)
  32. {
  33. int long long sum_transferred = 0;
  34. const char *byte_units[] = { "B", "KB", "MB", "GB", "TB" };
  35. unsigned max_unit = sizeof(byte_units) / sizeof(byte_units[0]);
  36. fprintf(stream, "\n#---------------------\n");
  37. fprintf(stream, "Data transfer stats:\n");
  38. int busid;
  39. int bus_cnt = starpu_bus_get_count();
  40. for (busid = 0; busid < bus_cnt; busid++)
  41. {
  42. char src_name[128], dst_name[128];
  43. int src, dst;
  44. src = starpu_bus_get_src(busid);
  45. dst = starpu_bus_get_dst(busid);
  46. struct starpu_profiling_bus_info bus_info;
  47. starpu_bus_get_profiling_info(busid, &bus_info);
  48. int long long transferred = bus_info.transferred_bytes;
  49. int long long transfer_cnt = bus_info.transfer_count;
  50. double elapsed_time = starpu_timing_timespec_to_us(&bus_info.total_time) / 1e6;
  51. unsigned unit = 0;
  52. double d = convert_to_byte_units(transferred, max_unit, &unit);
  53. double avg = (transfer_cnt != 0) ? (d / transfer_cnt) : 0;
  54. _starpu_memory_node_get_name(src, src_name, sizeof(src_name));
  55. _starpu_memory_node_get_name(dst, dst_name, sizeof(dst_name));
  56. fprintf(stream, "\t%s -> %s", src_name, dst_name);
  57. fprintf(stream, "\t%.2lf %s", d, byte_units[unit]);
  58. fprintf(stream, "\t%.2lf %s/s", d / elapsed_time, byte_units[unit]);
  59. fprintf(stream, "\t(transfers : %lld - avg %.2lf %s)\n", transfer_cnt, avg, byte_units[unit]);
  60. sum_transferred += transferred;
  61. }
  62. unsigned unit = 0;
  63. double d = convert_to_byte_units(sum_transferred, max_unit, &unit);
  64. fprintf(stream, "Total transfers: %.2lf %s\n", d, byte_units[unit]);
  65. fprintf(stream, "#---------------------\n");
  66. }
  67. void starpu_profiling_bus_helper_display_summary(void)
  68. {
  69. const char *stats;
  70. if (!((stats = starpu_getenv("STARPU_BUS_STATS")) && atoi(stats))) return;
  71. _starpu_profiling_bus_helper_display_summary(stderr);
  72. }
  73. void _starpu_profiling_worker_helper_display_summary(FILE *stream)
  74. {
  75. double sum_consumed = 0.;
  76. int profiling = starpu_profiling_status_get();
  77. double overall_time = 0;
  78. int workerid;
  79. int worker_cnt = starpu_worker_get_count();
  80. fprintf(stream, "\n#---------------------\n");
  81. fprintf(stream, "Worker stats:\n");
  82. for (workerid = 0; workerid < worker_cnt; workerid++)
  83. {
  84. struct starpu_profiling_worker_info info;
  85. starpu_profiling_worker_get_info(workerid, &info);
  86. char name[64];
  87. starpu_worker_get_name(workerid, name, sizeof(name));
  88. fprintf(stream, "%-32s\n", name);
  89. fprintf(stream, "\t%d task(s)\n", info.executed_tasks);
  90. if (profiling)
  91. {
  92. double total_time = starpu_timing_timespec_to_us(&info.total_time) / 1000.;
  93. double executing_time = starpu_timing_timespec_to_us(&info.executing_time) / 1000.;
  94. double sleeping_time = starpu_timing_timespec_to_us(&info.sleeping_time) / 1000.;
  95. if (total_time > overall_time)
  96. overall_time = total_time;
  97. fprintf(stream, "\ttotal: %.2lf ms executing: %.2lf ms sleeping: %.2lf ms overhead %.2lf ms\n",
  98. total_time, executing_time, sleeping_time, total_time - executing_time - sleeping_time);
  99. if (info.used_cycles || info.stall_cycles)
  100. fprintf(stream, "\t%llu Mcy %llu Mcy stall\n", (unsigned long long)info.used_cycles/1000000, (unsigned long long)info.stall_cycles/1000000);
  101. if (info.energy_consumed)
  102. fprintf(stream, "\t%f J consumed\n", info.energy_consumed);
  103. if (info.flops)
  104. fprintf(stream, "\t%f GFlop/s\n\n", info.flops / total_time / 1000000);
  105. }
  106. sum_consumed += info.energy_consumed;
  107. }
  108. if (profiling)
  109. {
  110. const char *strval_idle_power = starpu_getenv("STARPU_IDLE_POWER");
  111. if (strval_idle_power)
  112. {
  113. double idle_power = atof(strval_idle_power); /* Watt */
  114. double idle_energy = idle_power * overall_time / 1000.; /* J */
  115. fprintf(stream, "Idle energy: %.2lf J\n", idle_energy);
  116. fprintf(stream, "Total energy: %.2lf J\n",
  117. sum_consumed + idle_energy);
  118. }
  119. }
  120. fprintf(stream, "#---------------------\n");
  121. }
  122. void starpu_profiling_worker_helper_display_summary(void)
  123. {
  124. const char *stats;
  125. if (!((stats = starpu_getenv("STARPU_WORKER_STATS")) && atoi(stats))) return;
  126. _starpu_profiling_worker_helper_display_summary(stderr);
  127. }