From 5217d015bedf3103bfdbf94c1c4c6bebabde2dea Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 29 Mar 2017 16:50:29 -0400 Subject: [PATCH] a few little optimizations to take the edge off, 4.0.18 ready for publishing (barring problems durring test drive session) --- 4coder_lib/4coder_mem.h | 6 + 4ed.cpp | 84 ++++++------- 4ed.h | 2 + 4ed_api_implementation.cpp | 4 + 4ed_app_target.cpp | 1 + 4ed_buffer.cpp | 2 + 4ed_file.cpp | 7 ++ 4ed_file_view.cpp | 75 +++++++++--- 4ed_font_data.h | 8 ++ 4ed_font_static_functions.cpp | 32 ++++- 4ed_profile.cpp | 217 ++++++++++++++++++++++++++++++++++ 4ed_profile.h | 162 +++++++++++++++++++++++++ meta/build.cpp | 1 - project.4coder | 1 + run_profile.bat | 12 ++ win32_4ed.cpp | 6 +- 16 files changed, 553 insertions(+), 67 deletions(-) create mode 100644 4ed_profile.cpp create mode 100644 4ed_profile.h create mode 100644 run_profile.bat diff --git a/4coder_lib/4coder_mem.h b/4coder_lib/4coder_mem.h index 69ce0e1b..a7084b50 100644 --- a/4coder_lib/4coder_mem.h +++ b/4coder_lib/4coder_mem.h @@ -290,8 +290,14 @@ static i32_4tech general_memory_check(General_Memory *general){} #endif +#if !defined(PRFL_FUNC_GROUP) +#define PRFL_FUNC_GROUP() +#endif + static void* general_memory_allocate(General_Memory *general, i32_4tech size){ + PRFL_FUNC_GROUP(); + void *result = 0; if (size < BUBBLE_MIN_SIZE) size = BUBBLE_MIN_SIZE; for (Bubble *bubble = general->free_sentinel.next2; diff --git a/4ed.cpp b/4ed.cpp index bc9b7c69..58af3909 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -549,12 +549,11 @@ command_caller(Coroutine *coroutine){ Generic_Command generic; if (cmd_in->bind.function == command_user_callback){ generic.command = cmd_in->bind.custom; - models->command_caller(&models->app_links, generic); } else{ generic.cmdid = (Command_ID)cmd_in->bind.custom_id; - models->command_caller(&models->app_links, generic); } + models->command_caller(&models->app_links, generic); } else{ cmd_in->bind.function(command->system, command, cmd_in->bind); @@ -1171,56 +1170,46 @@ extern "C" SCROLL_RULE_SIG(fallback_scroll_rule){ } App_Init_Sig(app_init){ - Partition *partition; - Panel *panels, *panel; - Panel_Divider *dividers, *div; - i32 panel_max_count; - i32 divider_max_count; - App_Vars *vars = (App_Vars*)memory->vars_memory; Models *models = &vars->models; - models->keep_playing = 1; + models->keep_playing = true; app_links_init(system, &models->app_links, memory->user_memory, memory->user_memory_size); models->config_api = api; models->app_links.cmd_context = &vars->command_data; - partition = &models->mem.part; + Partition *partition = &models->mem.part; - { - panel_max_count = models->layout.panel_max_count = MAX_VIEWS; - divider_max_count = panel_max_count - 1; - models->layout.panel_count = 0; - - panels = push_array(partition, Panel, panel_max_count); - models->layout.panels = panels; - - dll_init_sentinel(&models->layout.free_sentinel); - dll_init_sentinel(&models->layout.used_sentinel); - - panel = panels; - for (i32 i = 0; i < panel_max_count; ++i, ++panel){ - dll_insert(&models->layout.free_sentinel, panel); - } - - dividers = push_array(partition, Panel_Divider, divider_max_count); - models->layout.dividers = dividers; - - div = dividers; - for (i32 i = 0; i < divider_max_count-1; ++i, ++div){ - div->next = (div + 1); - } - div->next = 0; - models->layout.free_divider = dividers; + PRFL_INIT(memory->debug_memory, memory->debug_memory_size); + + i32 panel_max_count = models->layout.panel_max_count = MAX_VIEWS; + i32 divider_max_count = panel_max_count - 1; + models->layout.panel_count = 0; + + Panel *panels = push_array(partition, Panel, panel_max_count); + models->layout.panels = panels; + + dll_init_sentinel(&models->layout.free_sentinel); + dll_init_sentinel(&models->layout.used_sentinel); + + Panel *panel = panels; + for (i32 i = 0; i < panel_max_count; ++i, ++panel){ + dll_insert(&models->layout.free_sentinel, panel); } + Panel_Divider *dividers = push_array(partition, Panel_Divider, divider_max_count); + models->layout.dividers = dividers; + + Panel_Divider *div = dividers; + for (i32 i = 0; i < divider_max_count-1; ++i, ++div){ + div->next = (div + 1); + } + div->next = 0; + models->layout.free_divider = dividers; + + { - View *view = 0; - View_Persistent *persistent = 0; - i32 i = 0; - i32 max = 0; - models->live_set = &vars->live_set; vars->live_set.count = 0; @@ -1230,12 +1219,12 @@ App_Init_Sig(app_init){ dll_init_sentinel(&vars->live_set.free_sentinel); - max = vars->live_set.max; - view = vars->live_set.views; - for (i = 0; i < max; ++i, ++view){ + i32 max = vars->live_set.max; + View *view = vars->live_set.views; + for (i32 i = 0; i < max; ++i, ++view){ dll_insert(&vars->live_set.free_sentinel, view); - persistent = &view->persistent; + View_Persistent *persistent = &view->persistent; persistent->id = i; persistent->models = models; } @@ -1515,8 +1504,7 @@ App_Init_Sig(app_init){ } internal i32 -update_cli_handle_without_file(System_Functions *system, Models *models, - CLI_Handles *cli, char *dest, i32 max){ +update_cli_handle_without_file(System_Functions *system, Models *models, CLI_Handles *cli, char *dest, i32 max){ i32 result = 0; u32 amount = 0; @@ -1567,6 +1555,8 @@ update_cli_handle_with_file(System_Functions *system, Models *models, CLI_Handle App_Step_Sig(app_step){ + PRFL_BEGIN_FRAME(); + Application_Step_Result app_result = *app_result_; app_result.animating = 0; @@ -2632,6 +2622,8 @@ App_Step_Sig(app_step){ *app_result_ = app_result; // end-of-app_step + + PRFL_END_FRAME("profile.data"); } extern "C" App_Get_Functions_Sig(app_get_functions){ diff --git a/4ed.h b/4ed.h index cbba946a..aeba7c7c 100644 --- a/4ed.h +++ b/4ed.h @@ -21,6 +21,8 @@ struct Application_Memory{ i32 target_memory_size; void *user_memory; i32 user_memory_size; + void *debug_memory; + i32 debug_memory_size; }; #define KEY_INPUT_BUFFER_SIZE 8 diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 24b4e84f..be457ddb 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -606,6 +606,8 @@ range is not within the bounds of the buffer. ) DOC_SEE(4coder_Buffer_Positioning_System) */{ + PRFL_FUNC_GROUP(); + Command_Data *cmd = (Command_Data*)app->cmd_context; Editing_File *file = imp_get_file(cmd, buffer); @@ -1114,6 +1116,8 @@ DOC_RETURN(returns a summary of the newly created buffer or of the existing buff DOC_SEE(begin_buffer_creation) */{ + PRFL_FUNC_GROUP(); + Command_Data *cmd = (Command_Data*)app->cmd_context; System_Functions *system = cmd->system; Models *models = cmd->models; diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index 88b699cc..3bda77fd 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -20,6 +20,7 @@ #include "4ed_math.h" #include "4ed_system.h" +#include "4ed_profile.h" //#define USE_DEBUG_MEMORY diff --git a/4ed_buffer.cpp b/4ed_buffer.cpp index 75163296..15a61715 100644 --- a/4ed_buffer.cpp +++ b/4ed_buffer.cpp @@ -669,6 +669,8 @@ buffer_measure_starts(Buffer_Measure_Starts *state, Gap_Buffer *buffer){ internal void buffer_measure_character_starts(System_Functions *system, Render_Font *font, Gap_Buffer *buffer, i32 *character_starts, i32 mode, i32 virtual_white){ + PRFL_FUNC_GROUP(); + assert(mode == 0); Gap_Buffer_Stream stream = {0}; diff --git a/4ed_file.cpp b/4ed_file.cpp index 6543dbcc..6250f708 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -106,6 +106,11 @@ struct Editing_File_Settings{ }; global_const Editing_File_Settings null_editing_file_settings = {0}; +struct Editing_Hacks{ + b32 suppression_mode; + b32 needs_wraps_and_fix_cursor; +}; + struct Editing_File_State{ Gap_Buffer buffer; @@ -140,6 +145,8 @@ struct Editing_File_State{ File_Edit_Positions edit_pos_space[16]; File_Edit_Positions *edit_poss[16]; i32 edit_poss_count; + + Editing_Hacks hacks; }; global_const Editing_File_State null_editing_file_state = {0}; diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index c847ba65..acb2f3ad 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -899,6 +899,8 @@ file_update_cursor_positions(System_Functions *system, Models *models, Editing_F internal void file_measure_starts(General_Memory *general, Gap_Buffer *buffer){ + PRFL_FUNC_GROUP(); + if (!buffer->line_starts){ i32 max = buffer->line_max = KB(1); buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32)); @@ -1453,6 +1455,8 @@ get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start){ internal void file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){ + PRFL_FUNC_GROUP(); + General_Memory *general = &models->mem.general; Partition *part = &models->mem.part; @@ -1509,12 +1513,20 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, i32 potential_count = 0; i32 stage = 0; + PRFL_BEGIN_RESUMABLE(buffer_measure_wrap_y); + PRFL_BEGIN_RESUMABLE(NeedWrapDetermination); + PRFL_BEGIN_RESUMABLE(NeedLineShift); + PRFL_BEGIN_RESUMABLE(LongTokenParsing); + do{ + PRFL_START_RESUMABLE(buffer_measure_wrap_y); stop = buffer_measure_wrap_y(&state, params, current_line_shift, do_wrap, wrap_unit_end); + PRFL_STOP_RESUMABLE(buffer_measure_wrap_y); switch (stop.status){ case BLStatus_NeedWrapDetermination: { + PRFL_START_RESUMABLE(NeedWrapDetermination); if (use_tokens){ if (stage == 0){ do_wrap = 0; @@ -1539,7 +1551,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, f32 self_x = 0; i32 wrap_end_result = size; if (buffer_stringify_loop(&stream, params.buffer, i, size)){ - b32 still_looping = 0; + b32 still_looping = false; do{ for (; i < stream.end; ++i){ { @@ -1594,11 +1606,13 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, do_wrap = 0; } } + PRFL_STOP_RESUMABLE(NeedWrapDetermination); }break; case BLStatus_NeedWrapLineShift: case BLStatus_NeedLineShift: { + PRFL_START_RESUMABLE(NeedLineShift); f32 current_width = width; if (use_tokens){ @@ -1636,8 +1650,8 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, b32 emit_comment_position = 0; b32 first_word = 1; - if (wrap_state.token_ptr->type == CPP_TOKEN_COMMENT || - wrap_state.token_ptr->type == CPP_TOKEN_STRING_CONSTANT){ + if (wrap_state.token_ptr->type == CPP_TOKEN_COMMENT || wrap_state.token_ptr->type == CPP_TOKEN_STRING_CONSTANT){ + PRFL_START_RESUMABLE(LongTokenParsing); i32 i = wrap_state.token_ptr->start; i32 end_i = i + wrap_state.token_ptr->size; @@ -1758,6 +1772,8 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, potential_marks[potential_count] = potential_wrap; ++potential_count; } + + PRFL_STOP_RESUMABLE(LongTokenParsing); } if (!emit_comment_position){ @@ -1928,10 +1944,17 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, file->state.line_indents[stop.wrap_line_index] = current_line_shift; file->state.wrap_line_count = stop.wrap_line_index; + + PRFL_STOP_RESUMABLE(NeedLineShift); }break; } }while(stop.status != BLStatus_Finished); + PRFL_END_RESUMABLE(buffer_measure_wrap_y); + PRFL_END_RESUMABLE(NeedWrapDetermination); + PRFL_END_RESUMABLE(NeedLineShift); + PRFL_END_RESUMABLE(LongTokenParsing); + ++file->state.wrap_line_count; file_allocate_wrap_positions_as_needed(general, file, wrap_position_index); @@ -1939,12 +1962,23 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, file->state.wrap_position_count = wrap_position_index; end_temp_memory(temp); + + if (file->state.hacks.needs_wraps_and_fix_cursor){ + file->state.hacks.needs_wraps_and_fix_cursor = false; + file_update_cursor_positions(system, models, file); + } } internal void file_measure_wraps_and_fix_cursor(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){ - file_measure_wraps(system, models, file, font); - file_update_cursor_positions(system, models, file); + if (file->state.hacks.suppression_mode){ + file->state.hacks.needs_wraps_and_fix_cursor = true; + } + else{ + file->state.hacks.needs_wraps_and_fix_cursor = false; + file_measure_wraps(system, models, file, font); + file_update_cursor_positions(system, models, file); + } } internal void @@ -1965,6 +1999,7 @@ file_set_min_base_width(System_Functions *system, Models *models, Editing_File * internal void file_create_from_string(System_Functions *system, Models *models, Editing_File *file, String val, b8 read_only = 0){ + PRFL_FUNC_GROUP(); General_Memory *general = &models->mem.general; Partition *part = &models->mem.part; @@ -1997,12 +2032,15 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File * file->settings.font_id = font_id; Render_Font *font = system->font.get_render_data_by_id(font_id); - file_measure_starts(general, &file->state.buffer); - - file_allocate_character_starts_as_needed(general, file); - buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); - - file_measure_wraps(system, models, file, font); + { + PRFL_SCOPE_GROUP(measurements); + file_measure_starts(general, &file->state.buffer); + + file_allocate_character_starts_as_needed(general, file); + buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); + + file_measure_wraps(system, models, file, font); + } file->settings.read_only = read_only; if (!read_only){ @@ -2034,7 +2072,13 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File * } if (hook_open_file){ + PRFL_SCOPE_GROUP(open_hook); + file->state.hacks.suppression_mode = true; hook_open_file(app_links, file->id.id); + file->state.hacks.suppression_mode = false; + if (file->state.hacks.needs_wraps_and_fix_cursor){ + file_measure_wraps_and_fix_cursor(system, models, file, font); + } } file->settings.is_initialized = true; } @@ -3218,9 +3262,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil scroll.scroll_y = y_position; } - view_set_cursor_and_scroll(view, new_cursor, - 1, view->file_data.file->settings.unwrapped_lines, - scroll); + view_set_cursor_and_scroll(view, new_cursor, 1, view->file_data.file->settings.unwrapped_lines, scroll); } } @@ -3319,8 +3361,7 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file } internal void -file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file, - Edit_Spec spec, History_Mode history_mode, i32 batch_type){ +file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file, Edit_Spec spec, History_Mode history_mode, i32 batch_type){ Mem_Options *mem = &models->mem; General_Memory *general = &mem->general; @@ -3771,6 +3812,8 @@ make_string_terminated(Partition *part, char *str, i32 len){ internal void init_normal_file(System_Functions *system, Models *models, Editing_File *file, char *buffer, i32 size){ + PRFL_FUNC_GROUP(); + String val = make_string(buffer, size); file_create_from_string(system, models, file, val); diff --git a/4ed_font_data.h b/4ed_font_data.h index 07231146..4274c2d6 100644 --- a/4ed_font_data.h +++ b/4ed_font_data.h @@ -45,6 +45,14 @@ struct Render_Font{ u32 name_len; char filename[256]; char name[256]; + + // Hack optimizations + struct Page_Cache{ + u32 page_number; + Glyph_Page *page; + }; + + Page_Cache cache[16]; }; struct Glyph_Data{ diff --git a/4ed_font_static_functions.cpp b/4ed_font_static_functions.cpp index 866d6365..806ee1db 100644 --- a/4ed_font_static_functions.cpp +++ b/4ed_font_static_functions.cpp @@ -79,7 +79,21 @@ font_get_glyph_advance(System_Functions *system, Render_Font *font, u32 codepoin f32 result = 0.f; u32 page_number = (codepoint >> 8); u32 glyph_index = codepoint & 0xFF; - Glyph_Page *page = font_get_or_make_page(system, font, page_number); + + Glyph_Page *page = 0; + + // Hack optimizations + u32 cache_index = page_number % ArrayCount(font->cache); + if (font->cache[cache_index].page_number == page_number){ + page = font->cache[cache_index].page; + } + + if (page == 0){ + page = font_get_or_make_page(system, font, page_number); + font->cache[cache_index].page = page; + font->cache[cache_index].page_number = page_number; + } + if (page != 0 && page->advance[glyph_index] > 0.f){ result = page->advance[glyph_index]; } @@ -91,7 +105,21 @@ font_get_glyph(System_Functions *system, Render_Font *font, u32 codepoint){ Glyph_Data result = {0}; u32 page_number = (codepoint >> 8); u32 glyph_index = codepoint & 0xFF; - Glyph_Page *page = font_get_or_make_page(system, font, page_number); + + Glyph_Page *page = 0; + + // Hack optimizations + u32 cache_index = page_number % ArrayCount(font->cache); + if (font->cache[cache_index].page_number == page_number){ + page = font->cache[cache_index].page; + } + + if (page == 0){ + page = font_get_or_make_page(system, font, page_number); + font->cache[cache_index].page = page; + font->cache[cache_index].page_number = page_number; + } + if (page != 0 && page->advance[glyph_index] > 0.f){ result.bounds = page->glyphs[glyph_index]; result.tex = page->tex; diff --git a/4ed_profile.cpp b/4ed_profile.cpp new file mode 100644 index 00000000..6926f3f8 --- /dev/null +++ b/4ed_profile.cpp @@ -0,0 +1,217 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 29.03.2017 + * + * Really basic profiling primitives. (not meant to stay for long) + * + */ + +// TOP + +#define FRED_INTERNAL 1 + +#include "4tech_defines.h" +#include "4ed_profile.h" + +#include +#include + +global f32 frame_target = 58000000.f; + +internal void +usage(){ + fprintf(stderr, "No! Like this, you moron:\n" + "\t [min-time-filter]\n"); +} + +internal u32 +parse_frame_count(u8 *ptr, u8 *end){ + u32 count = 0; + + for (;ptr < end;){ + u8 *frame_base = *(u8**)ptr; + ptr += 8; + + u8 *frame_end = *(u8**)ptr; + ptr += 8; + + umem skip_size = frame_end - frame_base; + ptr += skip_size; + ++count; + } + + if (ptr != end){ + count = 0; + } + + return(count); +} + +struct Parse_Frame_Result{ + u8 *next_read_ptr; + u8 *output_chunk; + b32 still_looping; + b32 bad_parse; + f32 frame_time; +}; + +internal Parse_Frame_Result +parse_frame(u8 *ptr, u8 *end_ptr){ + Parse_Frame_Result result = {0}; + + u8 *frame_base = *(u8**)ptr; + ptr += 8; + + u8 *frame_end = *(u8**)ptr; + ptr += 8; + + umem frame_size = frame_end - frame_base; + u8 *frame_start_ptr = ptr; + u8 *frame_end_ptr = ptr + frame_size; + + u8 *out_chunk = (u8*)malloc(frame_size*2); + u8 *out_ptr = out_chunk; + + Profile_Group *group = (Profile_Group*)frame_start_ptr; + Profile_Group *group_end = (Profile_Group*)frame_end_ptr; + + Profile_Group *stack[64]; + u32 top = 0; + + stack[top++] = group; + + result.frame_time = group->cycle_count / frame_target; + + for (;group < group_end;){ + for (u32 i = 1; i < top; ++i){ + *out_ptr++ = ' '; + } + + char *name = group->name; + for (u32 i = 0; name[i]; ++i){ + *out_ptr++ = name[i]; + } + + *out_ptr++ = ':'; + *out_ptr++ = ' '; + + char str[64]; + sprintf(str, "%f", group->cycle_count / frame_target); + for (u32 i = 0; str[i]; ++i){ + *out_ptr++ = str[i]; + } + *out_ptr++ = '\n'; + + ++group; + + for(;top > 0;){ + Profile_Group *group_top = stack[top-1]; + umem end_offset = (u8*)group_top->end - frame_base; + u8 *this_group_end_ptr = frame_start_ptr + end_offset; + Profile_Group *this_group_end = (Profile_Group*)this_group_end_ptr; + + if (group == this_group_end){ + --top; + } + else{ + break; + } + } + + stack[top++] = group; + } + + if (top != 1){ + result.bad_parse = true; + } + else{ + *out_ptr++ = 0; + result.next_read_ptr = frame_end_ptr; + result.output_chunk = out_chunk; + if (frame_end_ptr != end_ptr){ + result.still_looping = true; + } + } + + return(result); +} + +internal void +print_profile(char *filename, f32 min_filter){ + FILE *file = fopen(filename, "rb"); + if (!file){ + fprintf(stderr, "There ain't no file sittin' around called %s.\n", filename); + exit(1); + } + + fseek(file, 0, SEEK_END); + u32 size = ftell(file); + fseek(file, 0, SEEK_SET); + + u8 *buffer = (u8*)malloc(size); + + fread(buffer, 1, size, file); + fclose(file); + + u8 *read_ptr = buffer; + u8 *end_ptr = buffer + size; + + // Frame Count Parse + u32 frame_count = parse_frame_count(read_ptr, end_ptr); + + if (frame_count == 0){ + fprintf(stderr, "There's some fricken problem. I didn't get a good frame count!\n"); + exit(1); + } + + // Full Parse + u8 **output_chunks = (u8**)malloc(frame_count*sizeof(u8*)); + u32 chunk_i = 0; + + Parse_Frame_Result result = {0}; + do{ + if (chunk_i >= frame_count){ + fprintf(stderr, "The parse ain't lined up! You're fired!\n"); + exit(1); + } + + result = parse_frame(read_ptr, end_ptr); + + if (result.bad_parse){ + fprintf(stderr, "You've pickled the data nimwit!\n"); + exit(1); + } + + read_ptr = result.next_read_ptr; + if (result.frame_time >= min_filter){ + output_chunks[chunk_i++] = result.output_chunk; + } + }while(result.still_looping); + + // Print + fprintf(stdout, "Frames: %u (%u)\n", chunk_i, frame_count); + for (u32 i = 0; i < chunk_i; ++i){ + fprintf(stdout, "%s", output_chunks[i]); + } +} + +int main(int argc, char **argv){ + if (argc < 2){ + usage(); + } + else{ + f32 min_filter = 0.f; + if (argc == 3){ + min_filter = (f32)atof(argv[2]); + } + + print_profile(argv[1], min_filter); + } + return(0); +} + +// BOTTOM + + + diff --git a/4ed_profile.h b/4ed_profile.h new file mode 100644 index 00000000..42e1add5 --- /dev/null +++ b/4ed_profile.h @@ -0,0 +1,162 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 29.03.2017 + * + * Really basic profiling primitives. (not meant to stay for long) + * + */ + +// TOP + +#if !defined(FRED_PROFILE_H) +#define FRED_PROFILE_H + +#if FRED_INTERNAL + +#include +#include + +struct Profile_Group{ + char name[104]; + u64 cycle_start; + u64 cycle_count; + void *end; +}; + +struct Profile{ + u8 *buffer; + u32 pos, max; + + Profile_Group *stack[64]; + u32 stack_top; +}; +global Profile global_profile = {0}; + +internal Profile_Group* +push_group(char *name){ + Profile_Group *result = 0; + if (global_profile.pos + sizeof(Profile_Group) <= global_profile.max){ + result = (Profile_Group*)(global_profile.buffer + global_profile.pos); + global_profile.pos += sizeof(Profile_Group); + u32 i = 0; + for (; name[i] && i < sizeof(result->name)-1; ++i){ + result->name[i] = name[i]; + } + result->name[i] = 0; + result->cycle_start = __rdtsc(); + } + return(result); +} + +internal void +profile_init(void *mem, u32 max){ + global_profile.buffer = (u8*)mem; + global_profile.max = max; +} + +internal void +profile_begin_group(char *name){ + u32 stack_pos = global_profile.stack_top; + if (stack_pos < ArrayCount(global_profile.stack)){ + global_profile.stack[stack_pos] = push_group(name); + Assert(global_profile.stack[stack_pos] != 0); + ++global_profile.stack_top; + } +} + +internal void +profile_end_group(){ + Assert(global_profile.stack_top > 0); + u32 stack_pos = --global_profile.stack_top; + if (stack_pos < ArrayCount(global_profile.stack)){ + Profile_Group *group = global_profile.stack[stack_pos]; + Assert(group != 0); + group->cycle_count = __rdtsc() - group->cycle_start; + group->end = global_profile.buffer + global_profile.pos; + } +} + +internal void +profile_begin_frame(){ + global_profile.pos = 0; + global_profile.stack_top = 0; + profile_begin_group("*frame*"); +} + +internal void +profile_end_frame(char *filename){ + profile_end_group(); + Assert(global_profile.stack_top == 0); + + FILE *file = fopen(filename, "ab"); + Assert(file != 0); + fwrite(&global_profile.buffer, 8, 1, file); + + Profile_Group *first_group = (Profile_Group*)global_profile.buffer; + fwrite(&first_group->end, 8, 1, file); + + fwrite(global_profile.buffer, 1, global_profile.pos, file); + fclose(file); +} + +internal Profile_Group* +profile_begin_resumable(char *name){ + Profile_Group *result = push_group(name); + Assert(result != 0); + result->cycle_count = 0; + result->end = result + 1; + return(result); +} + +struct profile_scope{ + profile_scope(char *name){ + profile_begin_group(name); + } + + ~profile_scope(){ + profile_end_group(); + } +}; + +#define PRFL_INIT(m,s) profile_init(m,s) + +#define PRFL_BEGIN_FRAME() profile_begin_frame() +#define PRFL_END_FRAME(n) profile_end_frame(n) + +#define PRFL_BEGIN_GROUP(n) profile_begin_group(#n) +#define PRFL_END_GROUP() profile_end_group() +#define PRFL_SCOPE_GROUP(n) profile_scope SCOPE_##n(#n) + +#define PRFL_FUNC_GROUP() profile_scope SCOPE_FUNC(__FUNCTION__) + +#define PRFL_BEGIN_RESUMABLE(n) Profile_Group *PRFLGRP_##n = profile_begin_resumable(#n) +#define PRFL_START_RESUMABLE(n) PRFLGRP_##n->cycle_start = __rdtsc() +#define PRFL_STOP_RESUMABLE(n) PRFLGRP_##n->cycle_count += __rdtsc() - PRFLGRP_##n->cycle_start +#define PRFL_END_RESUMABLE(n) + +#else + +#define PRFL_INIT(m,s) + +#define PRFL_BEGIN_FRAME() +#define PRFL_END_FRAME(n) + +#define PRFL_BEGIN_GROUP(n) +#define PRFL_END_GROUP() +#define PRFL_SCOPE_GROUP(n) + +#define PRFL_FUNC_GROUP() + +#define PRFL_BEGIN_RESUMABLE(n) +#define PRFL_START_RESUMABLE(n) +#define PRFL_STOP_RESUMABLE(n) +#define PRFL_END_RESUMABLE(n) + +#endif + +#endif + +// BOTTOM + + diff --git a/meta/build.cpp b/meta/build.cpp index 9a25bc92..08aba24c 100644 --- a/meta/build.cpp +++ b/meta/build.cpp @@ -629,7 +629,6 @@ package(char *cdir){ copy_file(build_dir, "4ed" EXE, dir, 0, 0); copy_file(build_dir, "4ed_app" DLL, dir, 0, 0); copy_all (pack_data_dir, "*", dir); - //copy_file(0, "TODO.txt", dir, 0, 0); copy_file(data_dir, "release-config.4coder", dir, 0, "config.4coder"); get_4coder_dist_name(&str, true, zip_dir, tier, arch, "zip"); diff --git a/project.4coder b/project.4coder index 3cb7a834..aad1b04a 100644 --- a/project.4coder +++ b/project.4coder @@ -6,6 +6,7 @@ fkey_command_win[2] = {"site\\build.bat", "*compilation*", true , true }; fkey_command_win[3] = {"string\\build.bat", "*compilation*", true , true }; fkey_command_win[4] = {"echo build: x86 & build.bat /DDEV_BUILD_X86", "*compilation*", true , true }; fkey_command_win[5] = {"..\\misc\\run.bat", "*run*", false, false }; +fkey_command_win[6] = {"run_profile.bat", "*profile*", false, true }; fkey_command_win[12] = {"package.bat", "*package*", false, true }; fkey_command_linux[1] = {"echo build: x64 & ./build.sh", "*compilation*", true , true }; diff --git a/run_profile.bat b/run_profile.bat new file mode 100644 index 00000000..9139c688 --- /dev/null +++ b/run_profile.bat @@ -0,0 +1,12 @@ +@echo off + +SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX +SET OPTS=%OPTS% /GR- /EHa- /nologo /FC + +pushd ..\build +cl %OPTS% ..\code\4ed_profile.cpp /Zi /Feprofile +popd + +pushd ..\data\test +..\..\build\profile profile.data 0.4 +popd \ No newline at end of file diff --git a/win32_4ed.cpp b/win32_4ed.cpp index a51e12bb..d69fcb7e 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -2032,9 +2032,11 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS memory_vars.target_memory_size = MB(512); memory_vars.target_memory = VirtualAlloc(base, memory_vars.target_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - base = (LPVOID)0; memory_vars.user_memory_size = MB(2); - memory_vars.user_memory = VirtualAlloc(base, memory_vars.target_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + memory_vars.user_memory = system_memory_allocate(memory_vars.user_memory_size); + + memory_vars.debug_memory_size = MB(512); + memory_vars.debug_memory = system_memory_allocate(memory_vars.debug_memory_size); win32vars.target.max = MB(1); win32vars.target.push_buffer = (char*)system_memory_allocate(win32vars.target.max);