Skip to content

Commit

Permalink
Compute both implicit and explicit section times
Browse files Browse the repository at this point in the history
  • Loading branch information
emilienlemaire committed Sep 5, 2023
1 parent dfa56ed commit bbad458
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 43 deletions.
5 changes: 1 addition & 4 deletions cobc/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -13366,7 +13366,7 @@ output_entry_function (struct cb_program *prog, cb_tree entry,
if (prog->flag_void) {
output ("(void)");
} else {
output ("int res = ");
output ("return ");
}
if (!prog->nested_level) {
output ("%s_ (%d", prog->program_id, progid);
Expand Down Expand Up @@ -13428,9 +13428,6 @@ output_entry_function (struct cb_program *prog, cb_tree entry,
}
output (");");
output_newline ();
if (!prog->flag_void) {
output_line("return res;");
}
output_block_close ();
output_newline ();
}
Expand Down
121 changes: 82 additions & 39 deletions libcob/cobperf.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ get_str_index(const char *str, const char **arr, size_t arr_len)
{
for (size_t i = 0; i < arr_len; i++) {
if (arr[i] == NULL) return ULONG_MAX;
if (!strcmp(str, arr[i])) return i;
if (!strcmp (str, arr[i])) return i;
}

return ULONG_MAX;
Expand Down Expand Up @@ -105,26 +105,22 @@ cob_perf_enter_paragraph(const char *section, const char *paragraph)
// We should always have a section when entering a paragraph.
if (!section) return;

sec_idx = get_str_index(section, sections, sections_count);
sec_idx = get_str_index (section, sections, sections_count);
if (sec_idx == ULONG_MAX) {
fprintf (stderr, "[cob_perf] Could not find section %s, aborting profiling.\n", section);
is_init = false;
return;
}

para_idx = get_str_index(paragraph, para_per_sections[sec_idx], max_paragraphs_count);
para_idx = get_str_index (paragraph, para_per_sections[sec_idx], max_paragraphs_count);
if (para_idx == ULONG_MAX) {
fprintf (stderr, "[cob_perf] Could not find paragraph %s IN %s, aborting profiling.\n",
section, paragraph);
is_init = false;
return;
}

// If the paragraph entered is in another section than the current one, then we want to
// enter it too.
if (called_paragraphs[current_idx][0] != sec_idx) cob_perf_enter_section(section);

clock_gettime(CLOCK_MONOTONIC, &ts);
clock_gettime (CLOCK_MONOTONIC, &ts);

current_idx++;

Expand All @@ -140,15 +136,15 @@ cob_perf_enter_section(const char *section)
struct timespec ts;
if (!is_init) return;

sec_idx = get_str_index(section, sections, sections_count);
sec_idx = get_str_index (section, sections, sections_count);

if (sec_idx == ULONG_MAX) {
fprintf (stderr, "[cob_perf] Could not find section %s, aborting profiling.\n", section);
is_init = false;
return;
}

clock_gettime(CLOCK_MONOTONIC, &ts);
clock_gettime (CLOCK_MONOTONIC, &ts);

current_idx++;

Expand All @@ -165,24 +161,24 @@ cob_perf_exit_paragraph(const char *section, const char *paragraph)
struct timespec ts;
if (!is_init) return;

sec_idx = get_str_index(section, sections, sections_count);
sec_idx = get_str_index (section, sections, sections_count);

if (sec_idx == ULONG_MAX) {
fprintf(stderr, "[cob_perf] Could not find section %s, aborting profiling.\n", section);
fprintf (stderr, "[cob_perf] Could not find section %s, aborting profiling.\n", section);
is_init = false;
return;
}

para_idx = get_str_index(paragraph, para_per_sections[sec_idx], max_paragraphs_count);
para_idx = get_str_index (paragraph, para_per_sections[sec_idx], max_paragraphs_count);

if (para_idx == ULONG_MAX) {
fprintf(stderr, "[cob_perf] Could not find paragraph %s IN %s, aborting profiling.\n",
fprintf (stderr, "[cob_perf] Could not find paragraph %s IN %s, aborting profiling.\n",
section, paragraph);
is_init = false;
return;
}

clock_gettime(CLOCK_MONOTONIC, &ts);
clock_gettime (CLOCK_MONOTONIC, &ts);

while (current_idx != ULONG_MAX) {
size_t curr_sec = called_paragraphs[current_idx][0];
Expand All @@ -205,33 +201,38 @@ cob_perf_exit_section(const char *section)

if (!is_init) return;

sec_idx = get_str_index(section, sections, sections_count);
sec_idx = get_str_index (section, sections, sections_count);

if (sec_idx == ULONG_MAX) {
fprintf (stderr, "[cob_perf] Could not find section %s, aborting profiling.\n", section);
is_init = false;
return;
}

clock_gettime(CLOCK_MONOTONIC, &ts);
clock_gettime (CLOCK_MONOTONIC, &ts);

while (current_idx != ULONG_MAX) {
size_t curr_sec = called_paragraphs[current_idx][0];
size_t curr_para = called_paragraphs[current_idx][1];

if (curr_sec != sec_idx) return; // We exited all paragraphs entered in this section

if (curr_para == ULONG_MAX) {
total_times[curr_sec][254] += ts.tv_nsec - start_times[current_idx];
} else {
total_times[curr_sec][curr_para] += ts.tv_nsec - start_times[current_idx];
}
current_idx--;
if (curr_sec == sec_idx && curr_para == ULONG_MAX) return;
if (curr_sec == sec_idx && curr_para == ULONG_MAX) {
// We exit the last PERFORM of this section
return;
}
}
}

/* GO TO are generated for both explicit COBOL GO TO statements and COBOL EXIT ... statements.
* We do not need to have a paragraph/section enter function since these will be executed when
* the c goto is executed. */
* the c goto is executed, just after the targeted label. */
void
cob_perf_goto(const char *section, const char *paragraph)
{
Expand All @@ -244,27 +245,27 @@ cob_perf_goto(const char *section, const char *paragraph)
if (section == NULL) {

// GO TO exit : section = NULL, paragraph = invalid section name
if (get_str_index(paragraph, sections, sections_count) == ULONG_MAX) {
if (get_str_index (paragraph, sections, sections_count) == ULONG_MAX) {
return;
}

// GO TO section : section = NULL, paragraph = target section name
while (current_idx != ULONG_MAX) {
cob_perf_exit_section(sections[called_paragraphs[current_idx][0]]);
cob_perf_exit_section (sections[called_paragraphs[current_idx][0]]);
}

return;
}

sec_idx = get_str_index(section, sections, sections_count);
sec_idx = get_str_index (section, sections, sections_count);

if (sec_idx == ULONG_MAX) {
fprintf (stderr, "[cob_perf] Could not find section %s, aborting profiling.\n", section);
is_init = false;
return;
}

para_idx = get_str_index(paragraph, para_per_sections[sec_idx], max_paragraphs_count);
para_idx = get_str_index (paragraph, para_per_sections[sec_idx], max_paragraphs_count);

if (para_idx == ULONG_MAX) {
fprintf (stderr, "[cob_perf] Could not find paragraph %s IN %s, aborting profiling\n",
Expand All @@ -284,72 +285,114 @@ cob_perf_goto(const char *section, const char *paragraph)
}
} else {
while (current_idx != ULONG_MAX) {
cob_perf_exit_section(sections[called_paragraphs[current_idx][0]]);
cob_perf_exit_section (sections[called_paragraphs[current_idx][0]]);
}
}
}

#if WITH_XLSXWRITER
static unsigned
size_t_len(size_t s)
{
unsigned l = 1;
while (s > 9) {
l++;
s /= 10;
}
return l;
}
#endif

void
cob_perf_end()
{

#if WITH_XLSXWRITER
lxw_workbook *workbook;
lxw_worksheet *worksheet;
lxw_format *merge_format;
size_t row = 1;
size_t longest_sec = 7;
size_t longest_para = 9;
size_t longest_time = 9;
size_t longest_perform = 26;
#else
FILE *file;
#endif

if (!is_init) return;

while (current_idx != ULONG_MAX) {
cob_perf_exit_section(sections[called_paragraphs[current_idx][0]]);
cob_perf_exit_section (sections[called_paragraphs[current_idx][0]]);
}


#if WITH_XLSXWRITER
workbook = workbook_new("perf.xlsx");
worksheet = workbook_add_worksheet(workbook, NULL);
workbook = workbook_new ("perf.xlsx");
worksheet = workbook_add_worksheet (workbook, NULL);
merge_format = workbook_add_format(workbook);

worksheet_write_string(worksheet, 0, 0, "Section", NULL);
worksheet_write_string(worksheet, 0, 1, "Paragraph", NULL);
worksheet_write_string(worksheet, 0, 2, "Time (ns)", NULL);
format_set_align(merge_format, LXW_ALIGN_CENTER);
format_set_align(merge_format, LXW_ALIGN_VERTICAL_CENTER);
worksheet_write_string (worksheet, 0, 0, "Section", NULL);
worksheet_write_string (worksheet, 0, 1, "Paragraph", NULL);
worksheet_write_string (worksheet, 0, 2, "Time (ns)", NULL);
worksheet_write_string (worksheet, 0, 3, "Explicit section time (ns)", NULL);

for (size_t i = 0; i < sections_count; i++) {
size_t curr_sec_row = row;
long total_sec_time = 0;

worksheet_write_string(worksheet, row, 0, sections[i], NULL);
worksheet_write_number(worksheet, row, 2, (double)total_times[i][254], NULL);
worksheet_write_number (worksheet, row, 3, (double)total_times[i][254], NULL);
if (size_t_len (total_times[i][254]) > longest_time) longest_time =
size_t_len (total_times[i][254]);
row++;

for (size_t j = 0; j < max_paragraphs_count; j++) {
const char *para = para_per_sections[i][j];
if (para == NULL) break;

worksheet_write_string(worksheet, row, 0, sections[i], NULL);
worksheet_write_string(worksheet, row, 1, para, NULL);
worksheet_write_number(worksheet, row, 2, (double)total_times[i][j], NULL);
if (longest_para < strlen (para)) longest_para = strlen (para);
total_sec_time += total_times[i][j];
worksheet_write_string (worksheet, row, 1, para, NULL);
worksheet_write_number (worksheet, row, 2, (double)total_times[i][j], NULL);
if (size_t_len (total_times[i][j]) > longest_time) longest_time =
size_t_len (total_times[i][j]);
row++;
}
worksheet_write_number (worksheet, curr_sec_row, 2, total_sec_time, NULL);
worksheet_merge_range (worksheet, curr_sec_row, 0, row-1, 0, sections[i], merge_format);
if (strlen (sections[i]) > longest_sec) longest_sec = strlen (sections[i]);
if (size_t_len (total_sec_time) > longest_perform) longest_perform =
size_t_len (total_sec_time);
}

workbook_close(workbook);
worksheet_set_column (worksheet, 0, 0, ((double)longest_sec) + 0.43, NULL);
worksheet_set_column (worksheet, 1, 1, ((double)longest_para) + 0.43, NULL);
worksheet_set_column (worksheet, 2, 2, ((double)longest_time) + 0.43, NULL);
worksheet_set_column (worksheet, 3, 3, ((double)longest_perform) + 0.43, NULL);

workbook_close (workbook);

#else
file = fopen ("prof.csv", "W");
if (!!file) {
fprintf (file, "section, time\n");
fprintf (file, "section,paragraph,time,PERFORM section time\n");
for (size_t i = 0; i < sections_count; i++) {
fprintf (file, "%s, %lu ns\n", sections[i], total_times[i][254]);
long total_sec_time = 0;
fprintf (file, "%s, , , %lu ns\n", sections[i], total_times[i][254]);

for (size_t j = 0; j < max_paragraphs_count; j++) {
const char *para = para_per_sections[i][j];
if (para == NULL) break;

fprintf (file, "%s, %lu ns\n", para, total_times[i][j]);
total_sec_time += total_times[i][j];
}
fprintf (file, "%s, ,%lu ns, ", sections[i], total_sec_time);
}

fclose(file);
fclose (file);
}
#endif

Expand Down

0 comments on commit bbad458

Please sign in to comment.