From 3defb64946988857f32e17a7a577ca06f650e7f7 Mon Sep 17 00:00:00 2001 From: andreastaliad Date: Tue, 26 May 2026 17:42:42 +0300 Subject: [PATCH] made benchmarking changes for concurency; made finish line before sampling --- pi_digits_benchmark/README.md | 2 +- pi_digits_benchmark/pi_digits_benchmark | Bin 31016 -> 31064 bytes pi_digits_benchmark/pi_digits_benchmark.c | 63 +++++++++++------- .../run_pi_digits_benchmark.sh | 2 +- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/pi_digits_benchmark/README.md b/pi_digits_benchmark/README.md index 55f8ea1..802438a 100644 --- a/pi_digits_benchmark/README.md +++ b/pi_digits_benchmark/README.md @@ -29,5 +29,5 @@ Per-run outputs are stored under `runs/`: - `pi_digits.txt` — final concatenated digits - `workers.csv` — per-worker durations and chunk metadata -- `results.csv` — per-run summary metrics (includes aggregated RSS/VSZ and snapshot overhead) +- `results.csv` — per-run summary metrics (includes aggregated RSS/VSZ/PSS and snapshot overhead) - `stdout.log` / `stderr.log` — benchmark logs diff --git a/pi_digits_benchmark/pi_digits_benchmark b/pi_digits_benchmark/pi_digits_benchmark index d41562f46a2748b3ea1417a2fae571b10630d292..54178b9b5ddb094e259a7742e91a910e3947851e 100755 GIT binary patch delta 6959 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 z z8I1@E&FS8Buq-x@W%R$3Mz2lwy>Z;$*7#CjhcC%Pj3eqGm(dgb?U z5QN|z7+3B~QhavH81g`&j%NPC0%Vu|1(?o$SL4{+Z& ziJ+@!izbjI{g>g599ctyQih>2_zgm-MZuWhWV&XM7D$7;if=X|R70^ce3DV_n~CP_ z6*GLJWm90(4ySrV`x1&zXuRc)|CCC*$EG))cSu`Wv?}0jr>MZ-NRz{ph{@ZI>l$Wl~UYT+rlF<9kJA8&e);3u+xp#D5chDHT6NP_D60= zr94OX%hNiXLkPWwttjF~I(4FTQ~bt#61)aSY7Pkdlo)~|U`|kh1A>(_jKzSQVoOG) zSNsa^dg7}^f^f&^a=;JA+Xsv$5ZRYN@jZ8<;)|RMCS2<7XuU0zk%u1jk@oM3iNEkV zJ3lJTlwZW|kLsWMHE=@Rh#5+QJqBx`=v8+tGU0XL^~8Jl(}MOQc0U@qhdGMu@sIbf zrFIJs^Ax3sXV})F($p2?479ywr5NqK`!guw`SivgHI>~dDoZfaCtyoYS_36kVW!Pv zuHph`jfQ2=c?5i|UI*<6eQu%CUD&Sc4fjO%DVKT)=)DFSiTNxDH}=!_0rf8R?6YE} z*DJtj-h`^ z;M;}zDXsk~)WPl@R|sCveshhhSN9%G9$aNR#uS(qU1k3_W~iz9D(h*_Ha&Hf71+~F z_A6|v{h3}BSO;rjw3f^4H}-+O1{rg!_ReK?+CJP=b%mM7vT5r{ynh{><)_Msvtic0 zzeG6r?tp`PDbe_|$2z%2d!N{S_TwYSdzEqx&r2_wdChE4c8_4U#ulc(!)Jx7z(>8f zpsl^k7rp?57JG#`$EBMdUScndD@^?(4us-Q8}3qf$kkRfCJHRy`D^jF>@Ut7@dEqa`7`l% ztbTlx*v3YdPR8gdEf(EuZ)p~&7fTmqeoetcI2&%JAktm<9-$ssQU9qlwB#x35;#Y= zz?PQv>wO3xSg5Ng1&hCK+EVtDULO?1iNC1GZ<t`{@(lmWxWNQ`PzlPP zb$usb_Ln%M@RRv}b-jlCby3$h1HTB~IRU5v-T}M^FK6H!SHt~d0Pg|PA6in7JYIsx z&Ru|Okn61kQT>b9`l_tdU2VFK&k;c=i$V+p0oS8262GnNU{#j5nFXr`i8op7%t2#Q zfc+T16WH_L0fjP4fvFB@JoOm?-0#2-;z;hG2@R!LK}YDF0;31=Juq& zK5e?fj?Nt1leDb4%DQF_jGm9ztx)tK>tEg1WHqtk>XOLAKo+sJ)#&gl$6qa$dzv`OQXdp2TQ&yqwwZ>lK~b@64~j0!&Y)Ok*%cI>mgb;1-Vz9k zre`gk8k1)AOUQsoH{4kSH($WJKm^CE1XevOZ9rNJ3JxA}2Sp}4KY<0P8p6Y-Ewf4@ zSV7$K7%P=5Jb_W{+?-)zX;aMHqdiQ`v)HM5Lq!J@Ur6=@LM+j+fSzaYGYP$g6IA%{ za8CkO;z#%bR8xAm7XhEgkMoD{DIqzlL-O=f0LPaa^Op@E{2_!F1{nzMC%o=wyXPf)DA;@zD)f`jpF{ZiZuqZ5_&_)O zZQwB|9APa-RfPHg?u+Xf@DnjVopsG+PbY>2|QXWA^gYY@Y+VspCV|>!WaX-%ce#oi=VKm^M{Fl7PlZd^&$G!3?Wrm6f!<6?M2S{Dj)rP+{wp7d_2R)b{bO! zNU%b}nr;%Jm{^-E_T}SH8dDwMj5oy!fzt3U2As%wX7SO@N0pE7^6?Ws9^&H}KDN`C z`XID#cg>^N)P>2Sor#NS_w{(s;h18!dtq|wM5J7tfN%H;WA9J~3NttlJO=(+KCb8E z78>X61e+Bpva6eo0`T!j=!{TG@hS$vzYFo#cjMn1;%^&d>|Wf*fCudtUpg!W_~Hfq(`#R zFU@QE_@&IKrq&e~O-O`&?qSiPI0Q;rmwTeA6-;$Qmax_rss_kb, &metrics->max_vsz_kb); } -static int read_worker_stats(const char *path, long *rss_kb, long *vsz_kb) { - *rss_kb = 0; - *vsz_kb = 0; - FILE *f = fopen(path, "r"); - if (!f) { - return -1; - } - if (fscanf(f, "%ld,%ld", rss_kb, vsz_kb) != 2) { - fclose(f); - return -1; - } - fclose(f); - return 0; -} - static void aggregate_worker_memory(const bench_config_t *cfg, run_mode_t mode, const worker_info_t *workers, run_metrics_t *metrics) { double t0 = now_wall(); long total_rss = 0; long total_vsz = 0; + long total_pss = 0; long self_rss = 0; long self_vsz = 0; read_self_status_kb(&self_rss, &self_vsz); total_rss += self_rss; total_vsz += self_vsz; + total_pss += read_self_pss_kb(); if (mode == MODE_PROCESS) { for (long i = 0; i < cfg->process_count; ++i) { @@ -606,15 +613,22 @@ static void aggregate_worker_memory(const bench_config_t *cfg, run_mode_t mode, } long rss_kb = 0; long vsz_kb = 0; - if (read_worker_stats(workers[i].stats_path, &rss_kb, &vsz_kb) == 0) { + long pss_kb = 0; + FILE *f = fopen(workers[i].stats_path, "r"); + if (f && fscanf(f, "%ld,%ld,%ld", &rss_kb, &vsz_kb, &pss_kb) == 3) { + fclose(f); total_rss += rss_kb; total_vsz += vsz_kb; + total_pss += pss_kb; + } else if (f) { + fclose(f); } } } metrics->agg_rss_kb = total_rss; metrics->agg_vsz_kb = total_vsz; + metrics->agg_pss_kb = total_pss; metrics->mem_snapshot_s = now_wall() - t0; } @@ -635,13 +649,13 @@ static void write_results_csv(const char *results_csv, const char *run_id, const kernel[sizeof(kernel) - 1] = '\0'; } - fprintf(csv, "run_id,timestamp,host,kernel,mode,worker_count,pi_digits,chunk_size,exit_code,wall_s,cpu_user_s,cpu_sys_s,cpu_pct,max_rss_kb,max_vsz_kb,agg_rss_kb,agg_vsz_kb,mem_snapshot_s,final_output_bytes\n"); + fprintf(csv, "run_id,timestamp,host,kernel,mode,worker_count,pi_digits,chunk_size,exit_code,wall_s,cpu_user_s,cpu_sys_s,cpu_pct,max_rss_kb,max_vsz_kb,agg_rss_kb,agg_vsz_kb,agg_pss_kb,mem_snapshot_s,final_output_bytes\n"); long workers = (strcmp(mode, "thread") == 0) ? cfg->thread_count : cfg->process_count; - fprintf(csv, "%s,%s,%s,%s,%s,%ld,%ld,%ld,%d,%.6f,%.6f,%.6f,%.2f,%ld,%ld,%ld,%ld,%.6f,%zu\n", + fprintf(csv, "%s,%s,%s,%s,%s,%ld,%ld,%ld,%d,%.6f,%.6f,%.6f,%.2f,%ld,%ld,%ld,%ld,%ld,%.6f,%zu\n", run_id, ts, host, kernel, mode, workers, cfg->pi_digits, cfg->chunk_size, metrics->exit_code, metrics->wall_s, metrics->cpu_user_s, metrics->cpu_sys_s, metrics->cpu_pct, metrics->max_rss_kb, metrics->max_vsz_kb, - metrics->agg_rss_kb, metrics->agg_vsz_kb, metrics->mem_snapshot_s, metrics->output_bytes); + metrics->agg_rss_kb, metrics->agg_vsz_kb, metrics->agg_pss_kb, metrics->mem_snapshot_s, metrics->output_bytes); fclose(csv); } @@ -741,18 +755,17 @@ int main(int argc, char **argv) { metrics.exit_code = 1; } + double t_calc = now_wall(); + collect_metrics(&metrics, t0, t_calc); + aggregate_worker_memory(&cfg, mode, workers, &metrics); + int agg_rc = concatenate_outputs(&cfg, tmp_dir, final_path, worker_count); if (agg_rc != 0) { metrics.exit_code = 1; } - aggregate_worker_memory(&cfg, mode, workers, &metrics); - remove_dir_tree(tmp_dir); unlink(pid_file); - - double t1 = now_wall(); - collect_metrics(&metrics, t0, t1); metrics.output_bytes = file_size(final_path); write_results_csv(results_csv, run_id, mode_name, &cfg, &metrics); diff --git a/pi_digits_benchmark/run_pi_digits_benchmark.sh b/pi_digits_benchmark/run_pi_digits_benchmark.sh index 1c47527..ccc4017 100755 --- a/pi_digits_benchmark/run_pi_digits_benchmark.sh +++ b/pi_digits_benchmark/run_pi_digits_benchmark.sh @@ -20,7 +20,7 @@ RUN_ID=$(date +"%Y%m%d_%H%M%S") RESULTS_CSV="$DIR/results.csv" if [ ! -f "$RESULTS_CSV" ]; then - echo "run_id,timestamp,host,kernel,mode,worker_count,pi_digits,chunk_size,exit_code,wall_s,cpu_user_s,cpu_sys_s,cpu_pct,max_rss_kb,max_vsz_kb,agg_rss_kb,agg_vsz_kb,mem_snapshot_s,final_output_bytes" > "$RESULTS_CSV" + echo "run_id,timestamp,host,kernel,mode,worker_count,pi_digits,chunk_size,exit_code,wall_s,cpu_user_s,cpu_sys_s,cpu_pct,max_rss_kb,max_vsz_kb,agg_rss_kb,agg_vsz_kb,agg_pss_kb,mem_snapshot_s,final_output_bytes" > "$RESULTS_CSV" fi run_mode() {