with sufficient threads, split baking threads into two groups: small # of threads to do expensive 'background' baking tasks, use the rest to do wide predictable baking stuff

This commit is contained in:
Ryan Fleury
2025-09-05 15:19:29 -07:00
parent f065ca33a2
commit 8fe4b3524f
6 changed files with 1191 additions and 1076 deletions
-4
View File
@@ -996,8 +996,6 @@ X(RDI_U32, voff_range_first)\
X(RDI_U32, voff_range_opl)\ X(RDI_U32, voff_range_opl)\
X(RDI_U32, local_first)\ X(RDI_U32, local_first)\
X(RDI_U32, local_count)\ X(RDI_U32, local_count)\
X(RDI_U32, static_local_idx_run_first)\
X(RDI_U32, static_local_count)\
X(RDI_U32, inline_site_idx)\ X(RDI_U32, inline_site_idx)\
#define RDI_InlineSite_XList \ #define RDI_InlineSite_XList \
@@ -1446,8 +1444,6 @@ RDI_U32 voff_range_first;
RDI_U32 voff_range_opl; RDI_U32 voff_range_opl;
RDI_U32 local_first; RDI_U32 local_first;
RDI_U32 local_count; RDI_U32 local_count;
RDI_U32 static_local_idx_run_first;
RDI_U32 static_local_count;
RDI_U32 inline_site_idx; RDI_U32 inline_site_idx;
}; };
+10 -2
View File
@@ -335,7 +335,6 @@ rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys, RDI_U64 count)
// Also - this sort should be a "stable" sort. In the use case of sorting vmap // Also - this sort should be a "stable" sort. In the use case of sorting vmap
// ranges, we want to be able to rely on order, so it needs to be preserved here. // ranges, we want to be able to rely on order, so it needs to be preserved here.
RDIM_ProfBegin("rdim_sort_key_array");
RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); RDIM_Temp scratch = rdim_scratch_begin(&arena, 1);
RDIM_SortKey *result = 0; RDIM_SortKey *result = 0;
@@ -486,7 +485,6 @@ rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys, RDI_U64 count)
#endif #endif
rdim_scratch_end(scratch); rdim_scratch_end(scratch);
RDIM_ProfEnd();
return result; return result;
} }
@@ -1291,7 +1289,15 @@ rdim_bake_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_So
RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); RDIM_Temp scratch = rdim_scratch_begin(&arena, 1);
//- rjf: sort markers //- rjf: sort markers
#if 0
RDIM_SortKey *sorted_keys = rdim_sort_key_array(scratch.arena, keys, marker_count); RDIM_SortKey *sorted_keys = rdim_sort_key_array(scratch.arena, keys, marker_count);
#else
ProfBegin("sort markers");
RDIM_SortKey *sorted_keys = rdim_push_array(scratch.arena, RDIM_SortKey, marker_count);
rdim_memcpy(sorted_keys, keys, marker_count*sizeof(keys[0]));
radsort(sorted_keys, marker_count, rdim_sort_key_is_before);
ProfEnd();
#endif
//- rjf: determine if an extra vmap entry for zero is needed //- rjf: determine if an extra vmap entry for zero is needed
RDI_U32 extra_vmap_entry = 0; RDI_U32 extra_vmap_entry = 0;
@@ -1304,6 +1310,7 @@ rdim_bake_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_So
RDI_U32 vmap_count_raw = marker_count - 1 + extra_vmap_entry; RDI_U32 vmap_count_raw = marker_count - 1 + extra_vmap_entry;
RDI_VMapEntry *vmap = rdim_push_array(arena, RDI_VMapEntry, vmap_count_raw + 1); RDI_VMapEntry *vmap = rdim_push_array(arena, RDI_VMapEntry, vmap_count_raw + 1);
RDI_U32 vmap_entry_count_pass_1 = 0; RDI_U32 vmap_entry_count_pass_1 = 0;
ProfScope("fill output vmap entries")
{ {
typedef struct RDIM_VMapRangeTracker RDIM_VMapRangeTracker; typedef struct RDIM_VMapRangeTracker RDIM_VMapRangeTracker;
struct RDIM_VMapRangeTracker struct RDIM_VMapRangeTracker
@@ -1402,6 +1409,7 @@ rdim_bake_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_So
//- rjf: combine duplicate neighbors //- rjf: combine duplicate neighbors
RDI_U32 vmap_entry_count = 0; RDI_U32 vmap_entry_count = 0;
ProfScope("combine duplicate neighbors")
{ {
RDI_VMapEntry *vmap_ptr = vmap; RDI_VMapEntry *vmap_ptr = vmap;
RDI_VMapEntry *vmap_opl = vmap + vmap_entry_count_pass_1; RDI_VMapEntry *vmap_opl = vmap + vmap_entry_count_pass_1;
+1 -1
View File
@@ -1355,7 +1355,7 @@ internal Barrier
os_barrier_alloc(U64 count) os_barrier_alloc(U64 count)
{ {
OS_W32_Entity *entity = os_w32_entity_alloc(OS_W32_EntityKind_Barrier); OS_W32_Entity *entity = os_w32_entity_alloc(OS_W32_EntityKind_Barrier);
InitializeSynchronizationBarrier(&entity->sb, count, -1); BOOL init_good = InitializeSynchronizationBarrier(&entity->sb, count, -1);
Barrier result = {IntFromPtr(entity)}; Barrier result = {IntFromPtr(entity)};
return result; return result;
} }
-2
View File
@@ -1056,8 +1056,6 @@ RDI_ScopeMemberTable:
{voff_range_opl RDI_U32 ""} {voff_range_opl RDI_U32 ""}
{local_first RDI_U32 ""} {local_first RDI_U32 ""}
{local_count RDI_U32 ""} {local_count RDI_U32 ""}
{static_local_idx_run_first RDI_U32 ""}
{static_local_count RDI_U32 ""}
{inline_site_idx RDI_U32 ""} {inline_site_idx RDI_U32 ""}
} }
+125 -17
View File
@@ -10,9 +10,81 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params)
if(lane_idx() == 0) if(lane_idx() == 0)
{ {
rdim2_shared = push_array(arena, RDIM2_Shared, 1); rdim2_shared = push_array(arena, RDIM2_Shared, 1);
rdim2_shared->group_split = (lane_count() >= 2);
if(rdim2_shared->group_split)
{
rdim2_shared->group_0_lane_count = Clamp(1, lane_count()/2, 2);
rdim2_shared->group_0_barrier = barrier_alloc(rdim2_shared->group_0_lane_count);
rdim2_shared->group_1_barrier = barrier_alloc(lane_count() - rdim2_shared->group_0_lane_count);
}
} }
lane_sync(); lane_sync();
//////////////////////////////////////////////////////////////
//- rjf: with sufficient threads, split lanes into two groups:
//
// - group 0: one small group for many heterogeneous 'background' baking tasks
// - group 1: one large group for wide work we can reliably distribute
//
B32 group_0 = 1;
B32 group_1 = 1;
LaneCtx lane_ctx_restore = {0};
if(rdim2_shared->group_split)
{
if(lane_idx() < rdim2_shared->group_0_lane_count)
{
LaneCtx group_0_lane_ctx =
{
lane_idx(),
rdim2_shared->group_0_lane_count,
rdim2_shared->group_0_barrier
};
lane_ctx_restore = lane_ctx(group_0_lane_ctx);
group_0 = 1;
group_1 = 0;
}
else
{
LaneCtx group_1_lane_ctx =
{
lane_idx() - rdim2_shared->group_0_lane_count,
lane_count() - rdim2_shared->group_0_lane_count,
rdim2_shared->group_1_barrier
};
lane_ctx_restore = lane_ctx(group_1_lane_ctx);
group_0 = 0;
group_1 = 1;
}
}
//////////////////////////////////////////////////////////////
//- rjf: group 0
//
if(group_0)
{
ProfScope("bake all vmaps")
{
if(lane_idx() == lane_from_task_idx(0)) ProfScope("bake unit vmap")
{
rdim2_shared->baked_unit_vmap = rdim_bake_unit_vmap(arena, &params->units);
}
if(lane_idx() == lane_from_task_idx(1)) ProfScope("bake scope vmap")
{
rdim2_shared->baked_scope_vmap = rdim_bake_scope_vmap(arena, &params->scopes);
}
if(lane_idx() == lane_from_task_idx(2)) ProfScope("bake global vmap")
{
rdim2_shared->baked_global_vmap = rdim_bake_global_vmap(arena, &params->global_variables);
}
}
lane_sync();
}
//////////////////////////////////////////////////////////////
//- rjf: group 1
//
if(group_1)
{
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
//- rjf: build interned path tree //- rjf: build interned path tree
// //
@@ -29,7 +101,10 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params)
ProfScope("gather all unsorted, joined, line table info; & sort") ProfScope("gather all unsorted, joined, line table info; & sort")
{ {
//- rjf: set up outputs //- rjf: set up outputs
ProfScope("set up outputs") if(lane_idx() == 0) ProfScope("set up outputs")
{
// rjf: calculate header info
if(lane_idx() == 0)
{ {
rdim2_shared->line_tables_count = params->line_tables.total_count; rdim2_shared->line_tables_count = params->line_tables.total_count;
rdim2_shared->src_line_tables = push_array(arena, RDIM_LineTable *, rdim2_shared->line_tables_count); rdim2_shared->src_line_tables = push_array(arena, RDIM_LineTable *, rdim2_shared->line_tables_count);
@@ -49,19 +124,32 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params)
rdim2_shared->baked_line_tables.line_table_voffs_count = params->line_tables.total_line_count + 2*params->line_tables.total_seq_count; rdim2_shared->baked_line_tables.line_table_voffs_count = params->line_tables.total_line_count + 2*params->line_tables.total_seq_count;
rdim2_shared->baked_line_tables.line_table_lines_count = params->line_tables.total_line_count + params->line_tables.total_seq_count; rdim2_shared->baked_line_tables.line_table_lines_count = params->line_tables.total_line_count + params->line_tables.total_seq_count;
rdim2_shared->baked_line_tables.line_table_columns_count= 1; rdim2_shared->baked_line_tables.line_table_columns_count= 1;
rdim2_shared->line_table_block_take_counter = 0;
}
lane_sync();
// rjf: allocate outputs
ProfScope("allocate outputs") ProfScope("allocate outputs")
{
if(lane_idx() == lane_from_task_idx(0))
{ {
rdim2_shared->unsorted_joined_line_tables = push_array(arena, RDIM_UnsortedJoinedLineTable, rdim2_shared->line_tables_count); rdim2_shared->unsorted_joined_line_tables = push_array(arena, RDIM_UnsortedJoinedLineTable, rdim2_shared->line_tables_count);
rdim2_shared->sorted_line_table_keys = push_array(arena, RDIM_SortKey *, rdim2_shared->line_tables_count);
rdim2_shared->baked_line_tables.line_tables = push_array(arena, RDI_LineTable, rdim2_shared->baked_line_tables.line_tables_count);
rdim2_shared->baked_line_tables.line_table_voffs = push_array(arena, RDI_U64, rdim2_shared->baked_line_tables.line_table_voffs_count);
rdim2_shared->baked_line_tables.line_table_lines = push_array(arena, RDI_Line, rdim2_shared->baked_line_tables.line_table_lines_count);
rdim2_shared->baked_line_tables.line_table_columns = push_array(arena, RDI_Column, rdim2_shared->baked_line_tables.line_table_columns_count);
} }
if(lane_idx() == lane_from_task_idx(1))
{
rdim2_shared->sorted_line_table_keys = push_array(arena, RDIM_SortKey *, rdim2_shared->line_tables_count);
}
if(lane_idx() == lane_from_task_idx(2))
{
rdim2_shared->baked_line_tables.line_tables = push_array(arena, RDI_LineTable, rdim2_shared->baked_line_tables.line_tables_count);
// rjf: lay out line tables in joined info
ProfScope("lay out line tables")
{
U64 voffs_base_idx = 0; U64 voffs_base_idx = 0;
U64 lines_base_idx = 0; U64 lines_base_idx = 0;
U64 cols_base_idx = 0; U64 cols_base_idx = 0;
ProfScope("lay out line tables") for EachIndex(idx, rdim2_shared->line_tables_count) for EachIndex(idx, rdim2_shared->line_tables_count)
{ {
U64 final_idx = idx+1; // NOTE(rjf): +1, to reserve [0] for nil U64 final_idx = idx+1; // NOTE(rjf): +1, to reserve [0] for nil
RDIM_LineTable *src = rdim2_shared->src_line_tables[idx]; RDIM_LineTable *src = rdim2_shared->src_line_tables[idx];
@@ -73,14 +161,28 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params)
voffs_base_idx += src->line_count + 2*src->seq_count; voffs_base_idx += src->line_count + 2*src->seq_count;
lines_base_idx += src->line_count + 1*src->seq_count; lines_base_idx += src->line_count + 1*src->seq_count;
} }
rdim2_shared->line_table_block_take_counter = 0; }
}
if(lane_idx() == lane_from_task_idx(3))
{
rdim2_shared->baked_line_tables.line_table_voffs = push_array(arena, RDI_U64, rdim2_shared->baked_line_tables.line_table_voffs_count);
}
if(lane_idx() == lane_from_task_idx(4))
{
rdim2_shared->baked_line_tables.line_table_lines = push_array(arena, RDI_Line, rdim2_shared->baked_line_tables.line_table_lines_count);
}
if(lane_idx() == lane_from_task_idx(5))
{
rdim2_shared->baked_line_tables.line_table_columns = push_array(arena, RDI_Column, rdim2_shared->baked_line_tables.line_table_columns_count);
}
}
} }
lane_sync(); lane_sync();
//- rjf: wide bake //- rjf: wide bake
ProfScope("wide bake") ProfScope("wide bake")
{ {
U64 line_table_block_size = 4; U64 line_table_block_size = 4096;
U64 line_table_block_count = (rdim2_shared->line_tables_count + line_table_block_size - 1) / line_table_block_size; U64 line_table_block_count = (rdim2_shared->line_tables_count + line_table_block_size - 1) / line_table_block_size;
for(;;) for(;;)
{ {
@@ -1181,18 +1283,24 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params)
{ {
rdim2_shared->baked_binary_sections = rdim_bake_binary_sections(arena, bake_strings, &params->binary_sections); rdim2_shared->baked_binary_sections = rdim_bake_binary_sections(arena, bake_strings, &params->binary_sections);
} }
if(lane_idx() == lane_from_task_idx(2)) ProfScope("bake unit vmap")
{
rdim2_shared->baked_unit_vmap = rdim_bake_unit_vmap(arena, &params->units);
} }
if(lane_idx() == lane_from_task_idx(3)) ProfScope("bake scope vmap") lane_sync();
{
rdim2_shared->baked_scope_vmap = rdim_bake_scope_vmap(arena, &params->scopes);
} }
if(lane_idx() == lane_from_task_idx(4)) ProfScope("bake global vmap")
//////////////////////////////////////////////////////////////
//- rjf: on group split -> pop sub-lane-ctx, release barriers, join all lanes
//
if(rdim2_shared->group_split)
{ {
rdim2_shared->baked_global_vmap = rdim_bake_global_vmap(arena, &params->global_variables); if(group_0 && lane_idx() == 0)
{
barrier_release(rdim2_shared->group_0_barrier);
} }
if(group_1 && lane_idx() == 0)
{
barrier_release(rdim2_shared->group_1_barrier);
}
lane_ctx(lane_ctx_restore);
} }
lane_sync(); lane_sync();
+5
View File
@@ -21,6 +21,11 @@ struct RDIM_UnsortedJoinedLineTable
typedef struct RDIM2_Shared RDIM2_Shared; typedef struct RDIM2_Shared RDIM2_Shared;
struct RDIM2_Shared struct RDIM2_Shared
{ {
B32 group_split;
U64 group_0_lane_count;
Barrier group_0_barrier;
Barrier group_1_barrier;
RDIM_BakePathTree *path_tree; RDIM_BakePathTree *path_tree;
RDI_U64 line_tables_count; RDI_U64 line_tables_count;