draws sth 2
This commit is contained in:
@@ -1 +1,2 @@
|
||||
*.xlsx
|
||||
2/out
|
||||
|
||||
+36
-30
@@ -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
|
||||
|
||||
+66
-24
@@ -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 <logfile> [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()
|
||||
|
||||
Reference in New Issue
Block a user