Skip to content

Commit

Permalink
timing: add envvars for subsystem enable and verbose metadata
Browse files Browse the repository at this point in the history
This commit adds the following environment variables:
  - `JULIA_TIMING_SUBSYSTEMS` which can be set to, e.g.,
    "+INFERENCE,-GC,METHOD_MATCH" to enable INFERENCE
    and METHOD_MATCH and disable GC.
  - `JULIA_TIMING_METADATA_PRINT_LIMIT` which defaults
    to 10 and determines how many metadata items to add to
    a single timing zone before truncating

This commit also includes other miscellaneous changes to incorporate
review feedback.
  • Loading branch information
topolarity committed Apr 13, 2023
1 parent d82a5b5 commit 8e0cba5
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ static jl_callptr_t _jl_compile_codeinst(
size_t i = 0;
for (auto &def : emitted) {
jl_code_instance_t *this_code = def.first;
if (i < 10)
if (i < jl_timing_print_limit)
jl_timing_show_func_sig(this_code->def->specTypes, JL_TIMING_CURRENT_BLOCK);

jl_llvm_functions_t decls = std::get<1>(def.second);
Expand Down Expand Up @@ -297,7 +297,7 @@ static jl_callptr_t _jl_compile_codeinst(
fptr = addr;
i++;
}
if (i > 10)
if (i > jl_timing_print_limit)
jl_timing_printf(JL_TIMING_CURRENT_BLOCK, "... <%d methods truncated>", i - 10);

uint64_t end_time = 0;
Expand Down
7 changes: 5 additions & 2 deletions src/jlapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,8 +685,11 @@ static void rr_detach_teleport(void) {
JL_DLLEXPORT int jl_repl_entrypoint(int argc, char *argv[])
{
#ifdef USE_TRACY
if (getenv("WAIT_FOR_TRACY"))
while (!TracyCIsConnected) ; // Wait for connection
// Apply e.g. JULIA_TIMING_SUBSYSTEMS="+GC,-INFERENCE" and
// JULIA_TIMING_METADATA_PRINT_LIMIT=20
jl_timing_apply_env();
if (getenv("JULIA_WAIT_FOR_TRACY"))
while (!TracyCIsConnected) jl_cpu_pause(); // Wait for connection
#endif

// no-op on Windows, note that the caller must have already converted
Expand Down
2 changes: 0 additions & 2 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -1222,8 +1222,6 @@ CFI_NORETURN
_start_task();
}

const char* fiber = "task";

STATIC_OR_JS void NOINLINE JL_NORETURN _start_task(void)
{
CFI_NORETURN
Expand Down
81 changes: 74 additions & 7 deletions src/timing.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ JL_DLLEXPORT uint64_t jl_timing_enable_mask = 0xFFFFFFFFFFFFFFFF;
#endif

JL_DLLEXPORT uint64_t jl_timing_counts[(int)JL_TIMING_LAST] = {0};

// Used to as an item limit when several strings of metadata can
// potentially be associated with a single timing zone.
JL_DLLEXPORT uint32_t jl_timing_print_limit = 10;

const char *jl_timing_names[(int)JL_TIMING_LAST] =
{
#define X(name) #name
Expand Down Expand Up @@ -100,14 +105,16 @@ void jl_timing_block_enter_task(jl_task_t *ct, jl_ptls_t ptls, jl_timing_block_t
jl_timing_block_t *jl_timing_block_exit_task(jl_task_t *ct, jl_ptls_t ptls)
{
#ifdef USE_TRACY
// Tracy is fairly strict about not leaving a fiber that
// hasn't been entered, which happens often when
// connecting to a running Julia session.
// Tracy is fairly strict about not leaving a fiber that hasn't
// been entered, which happens often when connecting to a running
// Julia session.
//
// Eventually, Tracy will support telling the server which fibers
// are active upon connection, but until then we work around the
// problem by not explicitly leaving the fiber at all.
//
// Eventually, Tracy will support telling the server that
// which fibers are active upon connection, but until then
// work around around the problem by just entering the new
// fiber directly, which implicitly leaves any active fibers.
// Later when we enter the new fiber directly, that will cause the
// the active fiber to be left implicitly.

//TracyCFiberLeave;
#endif
Expand Down Expand Up @@ -220,11 +227,71 @@ JL_DLLEXPORT int jl_timing_set_enable(const char *subsystem, uint8_t enabled)
return -1;
}

static void jl_timing_set_enable_from_env(void)
{
const char *env = getenv("JULIA_TIMING_SUBSYSTEMS");
if (!env)
return;

// Copy `env`, so that we can modify it
size_t sz = strlen(env) + 1;
char *env_copy = (char *)malloc(sz);
memcpy(env_copy, env, sz);

char *subsystem = env_copy;
char *ch = subsystem;
uint8_t enable = 1;
while (1) {
// +SUBSYSTEM means enable, -SUBSYSTEM means disable
if (*subsystem == '+' || *subsystem == '-')
enable = (*subsystem++ == '+');

if (*ch == ',') {
*ch++ = '\0';
if ((*subsystem != '\0') && jl_timing_set_enable(subsystem, enable))
fprintf(stderr, "warning: unable to configure timing for non-existent subsystem \"%s\"\n", subsystem);

subsystem = ch;
enable = 1;
}
else if (*ch == '\0') {
if ((*subsystem != '\0') && jl_timing_set_enable(subsystem, enable))
fprintf(stderr, "warning: unable to configure timing for non-existent subsystem \"%s\"\n", subsystem);

break;
}
else ch++;
}
free(env_copy);
}

static void jl_timing_set_print_limit_from_env(void)
{
const char *const env = getenv("JULIA_TIMING_METADATA_PRINT_LIMIT");
if (!env)
return;

char *endp;
long value = strtol(env, &endp, 10);
if (*endp == '\0' && value >= 0 && value <= UINT32_MAX)
jl_timing_print_limit = (uint32_t)value;
}

void jl_timing_apply_env(void)
{
// JULIA_TIMING_SUBSYSTEMS
jl_timing_set_enable_from_env();

// JULIA_TIMING_METADATA_PRINT_LIMIT
jl_timing_set_print_limit_from_env();
}

#else

void jl_init_timing(void) { }
void jl_destroy_timing(void) { }
JL_DLLEXPORT int jl_timing_set_enable(const char *subsystem, uint8_t enabled) { return -1; }
JL_DLLEXPORT uint32_t jl_timing_print_limit = 0;

#endif

Expand Down
15 changes: 15 additions & 0 deletions src/timing.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ void jl_destroy_timing(void) JL_NOTSAFEPOINT;
// Returns -1 if no matching sub-system was found.
int jl_timing_set_enable(const char *subsystem, uint8_t enabled);

// Check for environment vars "JULIA_TIMING_METADATA_PRINT_LIMIT" and
// "JULIA_TIMING_SUBSYSTEMS" and if present apply these to the metadata
// print limit and the timings enable mask, respectively.
//
// For example, to enable INFERENCE and METHOD_MATCH and disable GC:
// JULIA_TIMING_SUBSYSTEMS="+INFERENCE,-GC,+METHOD_MATCH"
//
// For example, to increase the metadata item print limit from 10 to 20:
// JULIA_TIMING_METADATA_PRINT_LIMIT=20
void jl_timing_apply_env(void);

// Configurable item limit, runtime code should use this to limit printing
// when adding potentially many items of metadata to a single timing zone.
extern uint32_t jl_timing_print_limit;

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 8e0cba5

Please sign in to comment.