fxt.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2017 Université de Bordeaux
  4. * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 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. int _starpu_fxt_started = 0;
  35. starpu_pthread_mutex_t _starpu_fxt_started_mutex = STARPU_PTHREAD_MUTEX_INITIALIZER;
  36. starpu_pthread_cond_t _starpu_fxt_started_cond = STARPU_PTHREAD_COND_INITIALIZER;
  37. static int _starpu_written = 0;
  38. static int _starpu_id;
  39. static unsigned int initial_key_mask = FUT_KEYMASKALL;
  40. #ifdef STARPU_SIMGRID
  41. /* Give virtual time to FxT */
  42. uint64_t fut_getstamp(void)
  43. {
  44. return starpu_timing_now()*1000.;
  45. }
  46. #endif
  47. long _starpu_gettid(void)
  48. {
  49. /* TODO: test at configure whether __thread is available, and use that
  50. * to cache the value.
  51. * Don't use the TSD, this is getting called before we would have the
  52. * time to allocate it. */
  53. #ifdef STARPU_SIMGRID
  54. return (uintptr_t) MSG_process_self();
  55. #else
  56. #if defined(__linux__)
  57. return syscall(SYS_gettid);
  58. #elif defined(__FreeBSD__)
  59. long tid;
  60. thr_self(&tid);
  61. return tid;
  62. #elif defined(_WIN32) && !defined(__CYGWIN__)
  63. return (long) GetCurrentThreadId();
  64. #else
  65. return (long) pthread_self();
  66. #endif
  67. #endif
  68. }
  69. static void _starpu_profile_set_tracefile(void)
  70. {
  71. char *user;
  72. char *fxt_prefix = starpu_getenv("STARPU_FXT_PREFIX");
  73. if (!fxt_prefix)
  74. fxt_prefix = "/tmp/";
  75. snprintf(_STARPU_PROF_FILE_USER, 128, "%s", fxt_prefix);
  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();
  88. #ifdef HAVE_FUT_SET_FILENAME
  89. fut_set_filename(_STARPU_PROF_FILE_USER);
  90. #endif
  91. }
  92. void starpu_fxt_autostart_profiling(int autostart)
  93. {
  94. if (autostart)
  95. initial_key_mask = FUT_KEYMASKALL;
  96. else
  97. initial_key_mask = FUT_KEYMASK0;
  98. }
  99. void starpu_fxt_start_profiling()
  100. {
  101. unsigned threadid = _starpu_gettid();
  102. fut_keychange(FUT_ENABLE, FUT_KEYMASKALL, threadid);
  103. _STARPU_TRACE_EVENT("start_profiling");
  104. }
  105. void starpu_fxt_stop_profiling()
  106. {
  107. unsigned threadid = _starpu_gettid();
  108. _STARPU_TRACE_EVENT("stop_profiling");
  109. fut_keychange(FUT_DISABLE, FUT_KEYMASKALL, threadid);
  110. }
  111. void _starpu_fxt_init_profiling(unsigned trace_buffer_size)
  112. {
  113. unsigned threadid;
  114. if (!starpu_get_env_number_default("STARPU_FXT_TRACE", 1))
  115. return;
  116. STARPU_PTHREAD_MUTEX_LOCK(&_starpu_fxt_started_mutex);
  117. STARPU_ASSERT(!_starpu_fxt_started);
  118. _starpu_fxt_started = 1;
  119. _starpu_written = 0;
  120. _starpu_profile_set_tracefile();
  121. #ifdef HAVE_FUT_SET_FILENAME
  122. fut_set_filename(_STARPU_PROF_FILE_USER);
  123. #endif
  124. #ifdef HAVE_ENABLE_FUT_FLUSH
  125. // when the event buffer is full, fxt stops recording events.
  126. // The trace may thus be incomplete.
  127. // Enable the fut_flush function which is called when the
  128. // fxt event buffer is full to flush the buffer to disk,
  129. // therefore allowing to record the remaining events.
  130. enable_fut_flush();
  131. #endif
  132. threadid = _starpu_gettid();
  133. atexit(_starpu_stop_fxt_profiling);
  134. if (fut_setup(trace_buffer_size / sizeof(unsigned long), initial_key_mask, threadid) < 0)
  135. {
  136. perror("fut_setup");
  137. STARPU_ABORT();
  138. }
  139. STARPU_PTHREAD_COND_BROADCAST(&_starpu_fxt_started_cond);
  140. STARPU_PTHREAD_MUTEX_UNLOCK(&_starpu_fxt_started_mutex);
  141. return;
  142. }
  143. static void _starpu_generate_paje_trace(char *input_fxt_filename, char *output_paje_filename)
  144. {
  145. /* We take default options */
  146. struct starpu_fxt_options options;
  147. starpu_fxt_options_init(&options);
  148. /* TODO parse some STARPU_GENERATE_TRACE_OPTIONS env variable */
  149. options.ninputfiles = 1;
  150. options.filenames[0] = input_fxt_filename;
  151. options.out_paje_path = output_paje_filename;
  152. options.file_prefix = "";
  153. options.file_rank = -1;
  154. starpu_fxt_generate_trace(&options);
  155. }
  156. void _starpu_stop_fxt_profiling(void)
  157. {
  158. if (!_starpu_fxt_started)
  159. return;
  160. if (!_starpu_written)
  161. {
  162. #ifdef STARPU_VERBOSE
  163. char hostname[128];
  164. gethostname(hostname, 128);
  165. _STARPU_MSG("Writing FxT traces into file %s:%s\n", hostname, _STARPU_PROF_FILE_USER);
  166. #endif
  167. fut_endup(_STARPU_PROF_FILE_USER);
  168. /* Should we generate a Paje trace directly ? */
  169. int generate_trace = starpu_get_env_number("STARPU_GENERATE_TRACE");
  170. if (generate_trace == 1)
  171. _starpu_generate_paje_trace(_STARPU_PROF_FILE_USER, "paje.trace");
  172. int ret = fut_done();
  173. if (ret < 0)
  174. {
  175. /* Something went wrong with the FxT trace (eg. there
  176. * was too many events) */
  177. _STARPU_MSG("Warning: the FxT trace could not be generated properly\n");
  178. }
  179. _starpu_written = 1;
  180. _starpu_fxt_started = 0;
  181. }
  182. }
  183. void _starpu_fxt_register_thread(unsigned cpuid)
  184. {
  185. FUT_DO_PROBE2(FUT_NEW_LWP_CODE, cpuid, _starpu_gettid());
  186. }
  187. #else // STARPU_USE_FXT
  188. void starpu_fxt_autostart_profiling(int autostart STARPU_ATTRIBUTE_UNUSED)
  189. {
  190. }
  191. void starpu_fxt_start_profiling()
  192. {
  193. }
  194. void starpu_fxt_stop_profiling()
  195. {
  196. }
  197. #endif // STARPU_USE_FXT
  198. void starpu_fxt_trace_user_event(unsigned long code STARPU_ATTRIBUTE_UNUSED)
  199. {
  200. #ifdef STARPU_USE_FXT
  201. _STARPU_TRACE_USER_EVENT(code);
  202. #endif
  203. }
  204. void starpu_fxt_trace_user_event_string(const char *s STARPU_ATTRIBUTE_UNUSED)
  205. {
  206. #ifdef STARPU_USE_FXT
  207. _STARPU_TRACE_EVENT(s);
  208. #endif
  209. }