raddbgi_from_pdb: complete initial parallelization pass over string map building, joining, & sorting

This commit is contained in:
Ryan Fleury
2024-03-04 11:02:48 -08:00
parent 0ad795ba4c
commit 778f4eb08d
5 changed files with 169 additions and 56 deletions
+2 -2
View File
@@ -47,7 +47,7 @@ commands =
{
.rjf_f1 =
{
.win = "build raddbgi_from_pdb telemetry release",
.win = "build raddbgi_from_pdb telemetry debug",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
@@ -74,7 +74,7 @@ commands =
},
.rjf_f4 =
{
.win = "build raddbgi_from_pdb release telemetry && pushd build && raddbgi_from_pdb.exe --exe:raddbg.exe --pdb:raddbg.pdb --out:raddbg.raddbgi --capture && popd",
.win = "build raddbgi_from_pdb release telemetry && pushd build && raddbgi_from_pdb.exe --exe:UnrealEditorFortnite.exe --pdb:UnrealEditorFortnite.pdb --out:UnrealEditorFortnite.raddbgi --capture && popd",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
+6 -6
View File
@@ -1888,7 +1888,7 @@ rdim_bake_string_chunk_list_map_push_type_slice(RDIM_Arena *arena, RDIM_BakeStri
{
for(RDI_U64 idx = 0; idx < count; idx += 1)
{
rdim_bake_string_chunk_list_map_insert(arena, top, map, 64, v[idx].name);
rdim_bake_string_chunk_list_map_insert(arena, top, map, 4, v[idx].name);
}
}
@@ -1899,11 +1899,11 @@ rdim_bake_string_chunk_list_map_push_udt_slice(RDIM_Arena *arena, RDIM_BakeStrin
{
for(RDIM_UDTMember *mem = v[idx].first_member; mem != 0; mem = mem->next)
{
rdim_bake_string_chunk_list_map_insert(arena, top, map, 64, mem->name);
rdim_bake_string_chunk_list_map_insert(arena, top, map, 4, mem->name);
}
for(RDIM_UDTEnumVal *mem = v[idx].first_enum_val; mem != 0; mem = mem->next)
{
rdim_bake_string_chunk_list_map_insert(arena, top, map, 64, mem->name);
rdim_bake_string_chunk_list_map_insert(arena, top, map, 4, mem->name);
}
}
}
@@ -1913,8 +1913,8 @@ rdim_bake_string_chunk_list_map_push_symbol_slice(RDIM_Arena *arena, RDIM_BakeSt
{
for(RDI_U64 idx = 0; idx < count; idx += 1)
{
rdim_bake_string_chunk_list_map_insert(arena, top, map, 1, v[idx].name);
rdim_bake_string_chunk_list_map_insert(arena, top, map, 1, v[idx].link_name);
rdim_bake_string_chunk_list_map_insert(arena, top, map, 4, v[idx].name);
rdim_bake_string_chunk_list_map_insert(arena, top, map, 4, v[idx].link_name);
}
}
@@ -1925,7 +1925,7 @@ rdim_bake_string_chunk_list_map_push_scope_slice(RDIM_Arena *arena, RDIM_BakeStr
{
for(RDIM_Local *local = v[idx].first_local; local != 0; local = local->next)
{
rdim_bake_string_chunk_list_map_insert(arena, top, map, 1, local->name);
rdim_bake_string_chunk_list_map_insert(arena, top, map, 4, local->name);
}
}
}
+7 -1
View File
@@ -49,7 +49,11 @@
////////////////////////////////
//~ rjf: Hot, High Priority Tasks (Complete Unusability, Crashes, Fire-Worthy)
//
// [ ] DBGI layer is case-sensitive even on case-insensitive systems
// [ ] raddbg jai.exe my_file.jai -- foobar -> raddbg consumes `--` incorrectly
// [ ] PDB files distributed with the build are not found by DbgHelp!!!
// [ ] Jai compiler debugging crash
// [ ] raddbgi file regeneration too strict
//
// [ ] Jump table thunks, on code w/o /INCREMENTAL:NO
//
// [ ] ** Thread/process control bullet-proofing, including solo-step mode
@@ -73,6 +77,8 @@
// [ ] disasm animation & go-to-address
//
// [ ] visualize remapped files (via path map)
//
// [x] DBGI layer is case-sensitive even on case-insensitive systems
////////////////////////////////
//~ rjf: Hot, Medium Priority Tasks (Low-Hanging-Fruit Features, UI Jank, Cleanup)
+119 -45
View File
@@ -3516,14 +3516,51 @@ internal TS_TASK_FUNCTION_DEF(p2r_bake_udts_strings_task__entry_point)
internal TS_TASK_FUNCTION_DEF(p2r_bake_symbols_strings_task__entry_point)
{
P2R_BakeSymbolsStringsIn *in = (P2R_BakeSymbolsStringsIn *)p;
ProfScope("bake symbol strings") rdim_bake_string_chunk_list_map_push_symbols(arena, in->top, in->maps[thread_idx], in->list);
ProfScope("bake symbol strings")
{
for(P2R_BakeSymbolsStringsInNode *n = in->first; n != 0; n = n->next)
{
rdim_bake_string_chunk_list_map_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count);
}
}
return 0;
}
internal TS_TASK_FUNCTION_DEF(p2r_bake_scopes_strings_task__entry_point)
{
P2R_BakeScopesStringsIn *in = (P2R_BakeScopesStringsIn *)p;
ProfScope("bake scope strings") rdim_bake_string_chunk_list_map_push_scopes(arena, in->top, in->maps[thread_idx], in->list);
ProfScope("bake scope strings")
{
for(P2R_BakeScopesStringsInNode *n = in->first; n != 0; n = n->next)
{
rdim_bake_string_chunk_list_map_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count);
}
}
return 0;
}
//- rjf: bake string map joining
internal TS_TASK_FUNCTION_DEF(p2r_bake_string_map_join_task__entry_point)
{
P2R_JoinBakeStringMapSlotsIn *in = (P2R_JoinBakeStringMapSlotsIn *)p;
ProfScope("join bake string maps")
{
for(U64 src_map_idx = 0; src_map_idx < in->src_maps_count; src_map_idx += 1)
{
for(U64 slot_idx = in->slot_idx_range.min; slot_idx < in->slot_idx_range.max; slot_idx += 1)
{
if(in->dst_map->slots[slot_idx] == 0)
{
in->dst_map->slots[slot_idx] = in->src_maps[src_map_idx]->slots[slot_idx];
}
else if(in->src_maps[src_map_idx]->slots[slot_idx] != 0)
{
rdim_bake_string_chunk_list_concat_in_place(in->dst_map->slots[slot_idx], in->src_maps[src_map_idx]->slots[slot_idx]);
}
}
}
}
return 0;
}
@@ -3738,10 +3775,10 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in)
}
//- rjf: kick off string map building tasks
RDIM_BakeStringChunkListMapTopology bake_string_chunk_list_map_topology = {(params->procedures.total_count*2 +
params->global_variables.total_count*2 +
params->thread_variables.total_count*2 +
params->types.total_count*2)};
RDIM_BakeStringChunkListMapTopology bake_string_chunk_list_map_topology = {(params->procedures.total_count*1 +
params->global_variables.total_count*1 +
params->thread_variables.total_count*1 +
params->types.total_count/2)};
RDIM_BakeStringChunkListMap **bake_string_chunk_list_maps__in_progress = push_array(scratch.arena, RDIM_BakeStringChunkListMap *, ts_thread_count());
for(U64 idx = 0; idx < ts_thread_count(); idx += 1)
{
@@ -3750,6 +3787,7 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in)
TS_TicketList bake_string_map_build_tickets = {0};
{
// rjf: src files
ProfScope("kick off src files string map build task")
{
P2R_BakeSrcFilesStringsIn *in = push_array(scratch.arena, P2R_BakeSrcFilesStringsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
@@ -3759,6 +3797,7 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in)
}
// rjf: units
ProfScope("kick off units string map build task")
{
P2R_BakeUnitsStringsIn *in = push_array(scratch.arena, P2R_BakeUnitsStringsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
@@ -3768,11 +3807,12 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in)
}
// rjf: types
ProfScope("kick off types string map build tasks")
{
for(RDIM_TypeChunkNode *chunk = params->types.first; chunk != 0; chunk = chunk->next)
{
U64 types_per_task = Min(4096, chunk->count);
U64 tasks_per_this_chunk = (chunk->count+types_per_task-1)/types_per_task;
U64 items_per_task = Min(4096, chunk->count);
U64 tasks_per_this_chunk = (chunk->count+items_per_task-1)/items_per_task;
for(U64 task_idx = 0; task_idx < tasks_per_this_chunk; task_idx += 1)
{
P2R_BakeTypesStringsIn *in = push_array(scratch.arena, P2R_BakeTypesStringsIn, 1);
@@ -3780,19 +3820,20 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in)
in->maps = bake_string_chunk_list_maps__in_progress;
P2R_BakeTypesStringsInNode *n = push_array(scratch.arena, P2R_BakeTypesStringsInNode, 1);
SLLQueuePush(in->first, in->last, n);
n->v = chunk->v + task_idx*types_per_task;
n->count = types_per_task;
n->v = chunk->v + task_idx*items_per_task;
n->count = Min(items_per_task, chunk->count - task_idx*items_per_task);
ts_ticket_list_push(scratch.arena, &bake_string_map_build_tickets, ts_kickoff(p2r_bake_types_strings_task__entry_point, 0, in));
}
}
}
// rjf: UDTs
ProfScope("kick off udts string map build tasks")
{
for(RDIM_UDTChunkNode *chunk = params->udts.first; chunk != 0; chunk = chunk->next)
{
U64 udts_per_task = Min(4096, chunk->count);
U64 tasks_per_this_chunk = (chunk->count+udts_per_task-1)/udts_per_task;
U64 items_per_task = Min(4096, chunk->count);
U64 tasks_per_this_chunk = (chunk->count+items_per_task-1)/items_per_task;
for(U64 task_idx = 0; task_idx < tasks_per_this_chunk; task_idx += 1)
{
P2R_BakeUDTsStringsIn *in = push_array(scratch.arena, P2R_BakeUDTsStringsIn, 1);
@@ -3800,47 +3841,62 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in)
in->maps = bake_string_chunk_list_maps__in_progress;
P2R_BakeUDTsStringsInNode *n = push_array(scratch.arena, P2R_BakeUDTsStringsInNode, 1);
SLLQueuePush(in->first, in->last, n);
n->v = chunk->v + task_idx*udts_per_task;
n->count = udts_per_task;
n->v = chunk->v + task_idx*items_per_task;
n->count = Min(items_per_task, chunk->count - task_idx*items_per_task);
ts_ticket_list_push(scratch.arena, &bake_string_map_build_tickets, ts_kickoff(p2r_bake_udts_strings_task__entry_point, 0, in));
}
}
}
// rjf: global variables
// rjf: symbols
ProfScope("kick off symbols string map build tasks")
{
P2R_BakeSymbolsStringsIn *in = push_array(scratch.arena, P2R_BakeSymbolsStringsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
in->maps = bake_string_chunk_list_maps__in_progress;
in->list = &params->global_variables;
ts_ticket_list_push(scratch.arena, &bake_string_map_build_tickets, ts_kickoff(p2r_bake_symbols_strings_task__entry_point, 0, in));
}
// rjf: thread variables
{
P2R_BakeSymbolsStringsIn *in = push_array(scratch.arena, P2R_BakeSymbolsStringsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
in->maps = bake_string_chunk_list_maps__in_progress;
in->list = &params->thread_variables;
ts_ticket_list_push(scratch.arena, &bake_string_map_build_tickets, ts_kickoff(p2r_bake_symbols_strings_task__entry_point, 0, in));
}
// rjf: procedures
{
P2R_BakeSymbolsStringsIn *in = push_array(scratch.arena, P2R_BakeSymbolsStringsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
in->maps = bake_string_chunk_list_maps__in_progress;
in->list = &params->procedures;
ts_ticket_list_push(scratch.arena, &bake_string_map_build_tickets, ts_kickoff(p2r_bake_symbols_strings_task__entry_point, 0, in));
RDIM_SymbolChunkList *symbol_lists[] =
{
&params->global_variables,
&params->thread_variables,
&params->procedures,
};
for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1)
{
for(RDIM_SymbolChunkNode *chunk = symbol_lists[list_idx]->first; chunk != 0; chunk = chunk->next)
{
U64 items_per_task = Min(4096, chunk->count);
U64 tasks_per_this_chunk = (chunk->count+items_per_task-1)/items_per_task;
for(U64 task_idx = 0; task_idx < tasks_per_this_chunk; task_idx += 1)
{
P2R_BakeSymbolsStringsIn *in = push_array(scratch.arena, P2R_BakeSymbolsStringsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
in->maps = bake_string_chunk_list_maps__in_progress;
P2R_BakeSymbolsStringsInNode *n = push_array(scratch.arena, P2R_BakeSymbolsStringsInNode, 1);
SLLQueuePush(in->first, in->last, n);
n->v = chunk->v + task_idx*items_per_task;
n->count = Min(items_per_task, chunk->count - task_idx*items_per_task);
ts_ticket_list_push(scratch.arena, &bake_string_map_build_tickets, ts_kickoff(p2r_bake_symbols_strings_task__entry_point, 0, in));
}
}
}
}
// rjf: scope chunks
ProfScope("kick off scope chunks string map build tasks")
{
P2R_BakeScopesStringsIn *in = push_array(scratch.arena, P2R_BakeScopesStringsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
in->maps = bake_string_chunk_list_maps__in_progress;
in->list = &params->scopes;
ts_ticket_list_push(scratch.arena, &bake_string_map_build_tickets, ts_kickoff(p2r_bake_scopes_strings_task__entry_point, 0, in));
for(RDIM_ScopeChunkNode *chunk = params->scopes.first; chunk != 0; chunk = chunk->next)
{
U64 items_per_task = Min(4096, chunk->count);
U64 tasks_per_this_chunk = (chunk->count+items_per_task-1)/items_per_task;
for(U64 task_idx = 0; task_idx < tasks_per_this_chunk; task_idx += 1)
{
P2R_BakeScopesStringsIn *in = push_array(scratch.arena, P2R_BakeScopesStringsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
in->maps = bake_string_chunk_list_maps__in_progress;
P2R_BakeScopesStringsInNode *n = push_array(scratch.arena, P2R_BakeScopesStringsInNode, 1);
SLLQueuePush(in->first, in->last, n);
n->v = chunk->v + task_idx*items_per_task;
n->count = Min(items_per_task, chunk->count - task_idx*items_per_task);
ts_ticket_list_push(scratch.arena, &bake_string_map_build_tickets, ts_kickoff(p2r_bake_scopes_strings_task__entry_point, 0, in));
}
}
}
}
@@ -3869,9 +3925,27 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in)
RDIM_BakeStringChunkListMap *unsorted_bake_string_chunk_list_map = rdim_bake_string_chunk_list_map_make(arena, &bake_string_chunk_list_map_topology);
ProfScope("produce joined string map")
{
for(U64 idx = 0; idx < ts_thread_count(); idx += 1)
U64 slots_per_task = 16384;
U64 num_tasks = (bake_string_chunk_list_map_topology.slots_count+slots_per_task-1)/slots_per_task;
TS_Ticket *task_tickets = push_array(scratch.arena, TS_Ticket, num_tasks);
// rjf: kickoff tasks
for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1)
{
rdim_bake_string_chunk_list_map_join_in_place(&bake_string_chunk_list_map_topology, unsorted_bake_string_chunk_list_map, bake_string_chunk_list_maps__in_progress[idx]);
P2R_JoinBakeStringMapSlotsIn *in = push_array(scratch.arena, P2R_JoinBakeStringMapSlotsIn, 1);
in->top = &bake_string_chunk_list_map_topology;
in->src_maps = bake_string_chunk_list_maps__in_progress;
in->src_maps_count = ts_thread_count();
in->dst_map = unsorted_bake_string_chunk_list_map;
in->slot_idx_range = r1u64(task_idx*slots_per_task, task_idx*slots_per_task + slots_per_task);
in->slot_idx_range.max = Min(in->slot_idx_range.max, in->top->slots_count);
task_tickets[task_idx] = ts_kickoff(p2r_bake_string_map_join_task__entry_point, 0, in);
}
// rjf: join tasks
for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1)
{
ts_join(task_tickets[task_idx], max_U64);
}
}
+35 -2
View File
@@ -295,12 +295,29 @@ struct P2R_BakeUDTsStringsIn
P2R_BakeUDTsStringsInNode *last;
};
typedef struct P2R_BakeSymbolsStringsInNode P2R_BakeSymbolsStringsInNode;
struct P2R_BakeSymbolsStringsInNode
{
P2R_BakeSymbolsStringsInNode *next;
RDIM_Symbol *v;
RDI_U64 count;
};
typedef struct P2R_BakeSymbolsStringsIn P2R_BakeSymbolsStringsIn;
struct P2R_BakeSymbolsStringsIn
{
RDIM_BakeStringChunkListMapTopology *top;
RDIM_BakeStringChunkListMap **maps;
RDIM_SymbolChunkList *list;
P2R_BakeSymbolsStringsInNode *first;
P2R_BakeSymbolsStringsInNode *last;
};
typedef struct P2R_BakeScopesStringsInNode P2R_BakeScopesStringsInNode;
struct P2R_BakeScopesStringsInNode
{
P2R_BakeScopesStringsInNode *next;
RDIM_Scope *v;
RDI_U64 count;
};
typedef struct P2R_BakeScopesStringsIn P2R_BakeScopesStringsIn;
@@ -308,7 +325,20 @@ struct P2R_BakeScopesStringsIn
{
RDIM_BakeStringChunkListMapTopology *top;
RDIM_BakeStringChunkListMap **maps;
RDIM_ScopeChunkList *list;
P2R_BakeScopesStringsInNode *first;
P2R_BakeScopesStringsInNode *last;
};
//- rjf: string map joining task types
typedef struct P2R_JoinBakeStringMapSlotsIn P2R_JoinBakeStringMapSlotsIn;
struct P2R_JoinBakeStringMapSlotsIn
{
RDIM_BakeStringChunkListMapTopology *top;
RDIM_BakeStringChunkListMap **src_maps;
U64 src_maps_count;
RDIM_BakeStringChunkListMap *dst_map;
Rng1U64 slot_idx_range;
};
//- rjf: string map sorting task types
@@ -538,6 +568,9 @@ internal TS_TASK_FUNCTION_DEF(p2r_bake_udts_strings_task__entry_point);
internal TS_TASK_FUNCTION_DEF(p2r_bake_symbols_strings_task__entry_point);
internal TS_TASK_FUNCTION_DEF(p2r_bake_scopes_strings_task__entry_point);
//- rjf: bake string map joining
internal TS_TASK_FUNCTION_DEF(p2r_bake_string_map_join_task__entry_point);
//- rjf: bake string map sorting
internal TS_TASK_FUNCTION_DEF(p2r_bake_string_map_sort_task__entry_point);