fxt.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2015 Université de Bordeaux
  4. * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 CNRS
  5. *
  6. * StarPU is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation; either version 2.1 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * StarPU is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. *
  15. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  16. */
  17. #include <starpu.h>
  18. #include <common/config.h>
  19. #include <common/utils.h>
  20. #include <starpu_util.h>
  21. #include <starpu_profiling.h>
  22. #ifdef STARPU_USE_FXT
  23. #include <common/fxt.h>
  24. #include <starpu_fxt.h>
  25. #ifdef STARPU_HAVE_WINDOWS
  26. #include <windows.h>
  27. #endif
  28. #ifdef __linux__
  29. #include <sys/syscall.h> /* for SYS_gettid */
  30. #elif defined(__FreeBSD__)
  31. #include <sys/thr.h> /* for thr_self() */
  32. #endif
  33. static char _STARPU_PROF_FILE_USER[128];
  34. static int _starpu_fxt_started = 0;
  35. static int _starpu_written = 0;
  36. static int _starpu_id;
  37. #ifdef STARPU_SIMGRID
  38. /* Give virtual time to FxT */
  39. uint64_t fut_getstamp(void)
  40. {
  41. return starpu_timing_now()*1000.;
  42. }
  43. #endif
  44. long _starpu_gettid(void)
  45. {
  46. /* TODO: test at configure whether __thread is available, and use that
  47. * to cache the value.
  48. * Don't use the TSD, this is getting called before we would have the
  49. * time to allocate it. */
  50. #ifdef STARPU_SIMGRID
  51. return (uintptr_t) MSG_process_self();
  52. #else
  53. #if defined(__linux__)
  54. return syscall(SYS_gettid);
  55. #elif defined(__FreeBSD__)
  56. long tid;
  57. thr_self(&tid);
  58. return tid;
  59. #elif defined(_WIN32) && !defined(__CYGWIN__)
  60. return (long) GetCurrentThreadId();
  61. #else
  62. return (long) pthread_self();
  63. #endif
  64. #endif
  65. }
  66. static void _starpu_profile_set_tracefile(void *last, ...)
  67. {
  68. va_list vl;
  69. char *user;
  70. char *fxt_prefix = starpu_getenv("STARPU_FXT_PREFIX");
  71. if (!fxt_prefix)
  72. fxt_prefix = "/tmp/";
  73. va_start(vl, last);
  74. vsprintf(_STARPU_PROF_FILE_USER, fxt_prefix, vl);
  75. va_end(vl);
  76. user = starpu_getenv("USER");
  77. if (!user)
  78. user = "";
  79. char suffix[128];
  80. snprintf(suffix, 128, "prof_file_%s_%d", user, _starpu_id);
  81. strcat(_STARPU_PROF_FILE_USER, suffix);
  82. }
  83. void starpu_profiling_set_id(int new_id)
  84. {
  85. _STARPU_DEBUG("Set id to <%d>\n", new_id);
  86. _starpu_id = new_id;
  87. _starpu_profile_set_tracefile(NULL);
  88. #ifdef HAVE_FUT_SET_FILENAME
  89. fut_set_filename(_STARPU_PROF_FILE_USER);
  90. #endif
  91. }
  92. void starpu_fxt_start_profiling()
  93. {
  94. unsigned threadid = _starpu_gettid();
  95. fut_keychange(FUT_ENABLE, FUT_KEYMASKALL, threadid);
  96. _STARPU_TRACE_EVENT("start_profiling");
  97. }
  98. void starpu_fxt_stop_profiling()
  99. {
  100. unsigned threadid = _starpu_gettid();
  101. _STARPU_TRACE_EVENT("stop_profiling");
  102. fut_keychange(FUT_DISABLE, FUT_KEYMASKALL, threadid);
  103. }
  104. void _starpu_fxt_init_profiling(unsigned trace_buffer_size)
  105. {
  106. unsigned threadid;
  107. if (!_starpu_fxt_started)
  108. {
  109. _starpu_fxt_started = 1;
  110. _starpu_written = 0;
  111. _starpu_profile_set_tracefile(NULL);
  112. }
  113. #ifdef HAVE_FUT_SET_FILENAME
  114. fut_set_filename(_STARPU_PROF_FILE_USER);
  115. #endif
  116. #ifdef HAVE_ENABLE_FUT_FLUSH
  117. // when the event buffer is full, fxt stops recording events.
  118. // The trace may thus be incomplete.
  119. // Enable the fut_flush function which is called when the
  120. // fxt event buffer is full to flush the buffer to disk,
  121. // therefore allowing to record the remaining events.
  122. enable_fut_flush();
  123. #endif
  124. threadid = _starpu_gettid();
  125. atexit(_starpu_stop_fxt_profiling);
  126. unsigned int key_mask = FUT_KEYMASKALL;
  127. if (fut_setup(trace_buffer_size / sizeof(unsigned long), key_mask, threadid) < 0)
  128. {
  129. perror("fut_setup");
  130. STARPU_ABORT();
  131. }
  132. fut_keychange(FUT_ENABLE, key_mask, threadid);
  133. return;
  134. }
  135. static void _starpu_generate_paje_trace(char *input_fxt_filename, char *output_paje_filename)
  136. {
  137. /* We take default options */
  138. struct starpu_fxt_options options;
  139. starpu_fxt_options_init(&options);
  140. /* TODO parse some STARPU_GENERATE_TRACE_OPTIONS env variable */
  141. options.ninputfiles = 1;
  142. options.filenames[0] = input_fxt_filename;
  143. options.out_paje_path = output_paje_filename;
  144. options.file_prefix = "";
  145. options.file_rank = -1;
  146. starpu_fxt_generate_trace(&options);
  147. }
  148. void _starpu_stop_fxt_profiling(void)
  149. {
  150. if (!_starpu_written)
  151. {
  152. #ifdef STARPU_VERBOSE
  153. char hostname[128];
  154. gethostname(hostname, 128);
  155. fprintf(stderr, "Writing FxT traces into file %s:%s\n", hostname, _STARPU_PROF_FILE_USER);
  156. #endif
  157. fut_endup(_STARPU_PROF_FILE_USER);
  158. /* Should we generate a Paje trace directly ? */
  159. int generate_trace = starpu_get_env_number("STARPU_GENERATE_TRACE");
  160. if (generate_trace == 1)
  161. _starpu_generate_paje_trace(_STARPU_PROF_FILE_USER, "paje.trace");
  162. int ret = fut_done();
  163. if (ret < 0)
  164. {
  165. /* Something went wrong with the FxT trace (eg. there
  166. * was too many events) */
  167. fprintf(stderr, "Warning: the FxT trace could not be generated properly\n");
  168. }
  169. _starpu_written = 1;
  170. _starpu_fxt_started = 0;
  171. }
  172. }
  173. void _starpu_fxt_register_thread(unsigned cpuid)
  174. {
  175. FUT_DO_PROBE2(FUT_NEW_LWP_CODE, cpuid, _starpu_gettid());
  176. }
  177. #else // STARPU_USE_FXT
  178. void starpu_fxt_start_profiling()
  179. {
  180. }
  181. void starpu_fxt_stop_profiling()
  182. {
  183. }
  184. #endif // STARPU_USE_FXT
  185. void starpu_fxt_trace_user_event(unsigned long code STARPU_ATTRIBUTE_UNUSED)
  186. {
  187. #ifdef STARPU_USE_FXT
  188. _STARPU_TRACE_USER_EVENT(code);
  189. #endif
  190. }