From a96cc69e05941fe9e21756b57496f5c0fd884768 Mon Sep 17 00:00:00 2001 From: pajjilykk Date: Thu, 23 Apr 2026 11:29:39 +0700 Subject: [PATCH] draws sth 2 --- .gitignore | 1 + 2/Makefile | 66 +++++++++++++++++++---------------- 2/analyze_log.py | 90 +++++++++++++++++++++++++++++++++++------------- 3 files changed, 103 insertions(+), 54 deletions(-) diff --git a/.gitignore b/.gitignore index 7c12220..862b50f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.xlsx +2/out diff --git a/2/Makefile b/2/Makefile index d0c1063..6c24e11 100644 --- a/2/Makefile +++ b/2/Makefile @@ -4,46 +4,52 @@ CXXFLAGS = -O2 -std=c++17 -pthread TARGET = lab2 SRC = main.cpp -LOG = log.txt PY = python3 +# ================= BUILD ================= all: $(TARGET) $(TARGET): $(SRC) $(CXX) $(CXXFLAGS) $< -o $@ -# обычный запуск -run: $(TARGET) - ./$(TARGET) 20000 4 +# ================= BATCH 1 ================= +# FIXED THREAD COUNT = 2 +# VARYING WORKLOAD SIZE +batch_size: $(TARGET) + @echo "=== BATCH 1: scaling by size (threads = 2) ===" + ./$(TARGET) 5000 2 > log_size_5k.txt + ./$(TARGET) 10000 2 > log_size_10k.txt + ./$(TARGET) 20000 2 > log_size_20k.txt + ./$(TARGET) 50000 2 > log_size_50k.txt + ./$(TARGET) 100000 2 > log_size_100k.txt -# запуск с сохранением лога -log: $(TARGET) - ./$(TARGET) 20000 4 > $(LOG) +# ================= BATCH 2 ================= +# FIXED LARGE WORKLOAD +# VARYING THREAD COUNT +batch_threads: $(TARGET) + @echo "=== BATCH 2: scaling by threads (size = 200000) ===" + ./$(TARGET) 200000 0 > log_thr_0.txt + ./$(TARGET) 200000 2 > log_thr_2.txt + ./$(TARGET) 200000 4 > log_thr_4.txt + ./$(TARGET) 200000 8 > log_thr_8.txt -# анализ лога (таблица + график) -analyze: log - $(PY) analyze_log.py $(LOG) +# ================= FULL BENCH ================= +bench: batch_size batch_threads -# быстрый полный цикл -bench: $(TARGET) - @echo "Running benchmark..." - ./$(TARGET) 20000 0 > log_0.txt - ./$(TARGET) 20000 2 > log_2.txt - ./$(TARGET) 20000 4 > log_4.txt - ./$(TARGET) 20000 8 > log_8.txt +# ================= ANALYSIS ================= +analyze_size: + $(PY) analyze_log.py log_size_5k.txt out/size/ + $(PY) analyze_log.py log_size_10k.txt out/size/ + $(PY) analyze_log.py log_size_20k.txt out/size/ + $(PY) analyze_log.py log_size_50k.txt out/size/ + $(PY) analyze_log.py log_size_100k.txt out/size/ -# анализ конкретного лога -analyze0: - $(PY) analyze_log.py log_0.txt - -analyze2: - $(PY) analyze_log.py log_2.txt - -analyze4: - $(PY) analyze_log.py log_4.txt - -analyze8: - $(PY) analyze_log.py log_8.txt +analyze_threads: + $(PY) analyze_log.py log_thr_0.txt out/threads/ + $(PY) analyze_log.py log_thr_2.txt out/threads/ + $(PY) analyze_log.py log_thr_4.txt out/threads/ + $(PY) analyze_log.py log_thr_8.txt out/threads/ +# ================= CLEAN ================= clean: - rm -f $(TARGET) *.txt + rm -f $(TARGET) *.txt timeline.png diff --git a/2/analyze_log.py b/2/analyze_log.py index 934015f..4ae268d 100644 --- a/2/analyze_log.py +++ b/2/analyze_log.py @@ -1,27 +1,42 @@ +import os import re import sys from collections import defaultdict -# ================= BACKEND FIX (IMPORTANT FOR HYPRLAND) ================= import matplotlib try: - # Wayland / Hyprland recommended backend matplotlib.use("QtAgg") except Exception: - # fallback for headless systems matplotlib.use("Agg") import matplotlib.pyplot as plt # ================= INPUT ================= if len(sys.argv) < 2: - print("Usage: python analyze_log.py log.txt") + print("Usage: python analyze_log.py [output_dir]") sys.exit(1) logfile = sys.argv[1] +out_dir = sys.argv[2] if len(sys.argv) >= 3 else "out" -# ================= PARSE LOG ================= +# ================= PATH LOGIC ================= +base_name = os.path.splitext(os.path.basename(logfile))[0] + +# normalize folder structure +out_dir = os.path.normpath(out_dir) + +pics_dir = os.path.join(out_dir, "pics") +tables_dir = os.path.join(out_dir, "tables") + +os.makedirs(pics_dir, exist_ok=True) +os.makedirs(tables_dir, exist_ok=True) + +output_png = os.path.join(pics_dir, f"{base_name}.png") +output_md = os.path.join(tables_dir, f"{base_name}.md") + + +# ================= PARSE ================= pattern = re.compile(r"(START|END).*TID=(\d+).*range=\[(\d+),(\d+)\].*time=([\d.]+)") events = defaultdict(dict) @@ -36,6 +51,7 @@ with open(logfile) as f: key = (tid, int(l), int(r)) events[key][typ] = float(t) + # ================= BUILD ROWS ================= rows = [] @@ -61,40 +77,66 @@ if not rows: print("No valid events found") sys.exit(1) + # ================= OFFSET ================= t0 = rows[0]["start"] - for r in rows: r["offset"] = r["start"] - t0 -# ================= PRINT TABLE ================= -print("\n## TABLE\n") -print("| TID | Range | Start | End | Duration | Offset |") -print("|-----|-------|-------|-----|----------|--------|") -for r in rows: - print( - f"| {r['tid']} | {r['range']} | " - f"{r['start']:.6f} | {r['end']:.6f} | " - f"{r['duration']:.6f} | {r['offset']:.6f} |" - ) +# ================= COLOR MAP (LOGICAL) ================= +unique_tids = sorted(set(r["tid"] for r in rows)) + +color_map = { + tid: plt.cm.tab20(i % 20) # stable, readable palette + for i, tid in enumerate(unique_tids) +} + + +# ================= SAVE MARKDOWN ================= +with open(output_md, "w") as f: + f.write("# Execution Table\n\n") + f.write("| TID | Range | Start | End | Duration | Offset |\n") + f.write("|-----|-------|-------|-----|----------|--------|\n") + + for r in rows: + f.write( + f"| {r['tid']} | {r['range']} | " + f"{r['start']:.6f} | {r['end']:.6f} | " + f"{r['duration']:.6f} | {r['offset']:.6f} |\n" + ) + +print(f"[OK] Table saved: {output_md}") + # ================= PLOT ================= -plt.figure(figsize=(10, 6)) +plt.figure(figsize=(12, 6)) for i, r in enumerate(rows): - plt.plot([r["offset"], r["offset"] + r["duration"]], [i, i], linewidth=4) + plt.plot( + [r["offset"], r["offset"] + r["duration"]], + [i, i], + color=color_map[r["tid"]], + linewidth=4, + ) + +# legend (TID → color) +for tid in unique_tids: + plt.plot([], [], color=color_map[tid], label=f"TID {tid}") + +plt.legend(loc="upper right", fontsize=8) plt.xlabel("Time (seconds from start)") plt.ylabel("Tasks") -plt.title("Execution Timeline") +plt.title(f"Execution Timeline: {base_name}") plt.grid(True) plt.tight_layout() -# ================= SAVE (IMPORTANT FOR LAB) ================= -plt.savefig("timeline.png", dpi=200) -print("\nSaved: timeline.png") +# ================= SAVE IMAGE ================= +plt.savefig(output_png, dpi=200) +print(f"[OK] Plot saved: {output_png}") -# ================= SHOW (HYPRLAND WINDOW) ================= -plt.show() + +# ================= SHOW ================= +# plt.show()