From 5c27225465ac913927828d377d6c7ddd70a8dd0a Mon Sep 17 00:00:00 2001 From: pajjilykk Date: Thu, 23 Apr 2026 11:17:56 +0700 Subject: [PATCH] init come kind of 2 --- 2/Makefile | 35 ++++++++++++++++- 2/analyze_log.py | 100 +++++++++++++++++++++++++++++++++++++++++++++++ 2/lab2 | Bin 29824 -> 0 bytes 2/main.cpp | 89 +++++++++++++++++++++-------------------- req.txt | 2 + 5 files changed, 182 insertions(+), 44 deletions(-) create mode 100644 2/analyze_log.py delete mode 100755 2/lab2 diff --git a/2/Makefile b/2/Makefile index e44dafa..d0c1063 100644 --- a/2/Makefile +++ b/2/Makefile @@ -4,13 +4,46 @@ CXXFLAGS = -O2 -std=c++17 -pthread TARGET = lab2 SRC = main.cpp +LOG = log.txt +PY = python3 + all: $(TARGET) $(TARGET): $(SRC) $(CXX) $(CXXFLAGS) $< -o $@ +# обычный запуск run: $(TARGET) ./$(TARGET) 20000 4 +# запуск с сохранением лога +log: $(TARGET) + ./$(TARGET) 20000 4 > $(LOG) + +# анализ лога (таблица + график) +analyze: log + $(PY) analyze_log.py $(LOG) + +# быстрый полный цикл +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 + +# анализ конкретного лога +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 + clean: - rm -f $(TARGET) + rm -f $(TARGET) *.txt diff --git a/2/analyze_log.py b/2/analyze_log.py new file mode 100644 index 0000000..934015f --- /dev/null +++ b/2/analyze_log.py @@ -0,0 +1,100 @@ +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") + sys.exit(1) + +logfile = sys.argv[1] + +# ================= PARSE LOG ================= +pattern = re.compile(r"(START|END).*TID=(\d+).*range=\[(\d+),(\d+)\].*time=([\d.]+)") + +events = defaultdict(dict) + +with open(logfile) as f: + for line in f: + m = pattern.search(line) + if not m: + continue + + typ, tid, l, r, t = m.groups() + key = (tid, int(l), int(r)) + events[key][typ] = float(t) + +# ================= BUILD ROWS ================= +rows = [] + +for (tid, l, r), v in events.items(): + if "START" in v and "END" in v: + start = v["START"] + end = v["END"] + duration = end - start + + rows.append( + { + "tid": tid, + "range": f"[{l},{r}]", + "start": start, + "end": end, + "duration": duration, + } + ) + +rows.sort(key=lambda x: x["start"]) + +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} |" + ) + +# ================= PLOT ================= +plt.figure(figsize=(10, 6)) + +for i, r in enumerate(rows): + plt.plot([r["offset"], r["offset"] + r["duration"]], [i, i], linewidth=4) + +plt.xlabel("Time (seconds from start)") +plt.ylabel("Tasks") +plt.title("Execution Timeline") +plt.grid(True) +plt.tight_layout() + +# ================= SAVE (IMPORTANT FOR LAB) ================= +plt.savefig("timeline.png", dpi=200) + +print("\nSaved: timeline.png") + +# ================= SHOW (HYPRLAND WINDOW) ================= +plt.show() diff --git a/2/lab2 b/2/lab2 deleted file mode 100755 index 4bb7c3cd4f60d6d2a0c54166d78d41ea239f86cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29824 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 #include #include -#include // ✅ getpid +#include #include #include +#include // ================= CONFIG ================= constexpr int kDefaultN = 20000; constexpr int kPreviewCount = 20; -// ================= GLOBALS ================= +// ================= GLOBAL CONTROL ================= int active_threads = 0; int max_threads = 4; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER; +std::mutex log_mutex; // ================= TIME ================= double get_time() { @@ -36,38 +39,44 @@ std::string now() { return oss.str(); } -// ================= LOG ================= +// ================= SAFE LOGGING ================= void log_start(int l, int r, int depth) { + std::lock_guard lock(log_mutex); + std::cout << "START PID=" << getpid() << " TID=" << pthread_self() << " depth=" << depth - << " range=[" << l << "," << r << "] time=" << now() << '\n'; + << " range=[" << l << "," << r << "] time=" << now() + << '\n'; } void log_end(int l, int r, int depth) { + std::lock_guard lock(log_mutex); + std::cout << "END PID=" << getpid() << " TID=" << pthread_self() << " depth=" << depth - << " range=[" << l << "," << r << "] time=" << now() << '\n'; + << " range=[" << l << "," << r << "] time=" << now() + << '\n'; } // ================= MERGE ================= void merge_range(int* arr, int l, int m, int r) { - std::vector temp; - temp.reserve(r - l + 1); + std::vector tmp; + tmp.reserve(r - l + 1); int i = l; int j = m + 1; while (i <= m && j <= r) { - if (arr[i] <= arr[j]) temp.push_back(arr[i++]); - else temp.push_back(arr[j++]); + if (arr[i] <= arr[j]) tmp.push_back(arr[i++]); + else tmp.push_back(arr[j++]); } - while (i <= m) temp.push_back(arr[i++]); - while (j <= r) temp.push_back(arr[j++]); + while (i <= m) tmp.push_back(arr[i++]); + while (j <= r) tmp.push_back(arr[j++]); - std::copy(temp.begin(), temp.end(), arr + l); + std::copy(tmp.begin(), tmp.end(), arr + l); } // ================= LOCAL SORT ================= @@ -80,7 +89,7 @@ void local_sort(int* arr, int l, int r) { merge_range(arr, l, m, r); } -// ================= THREAD ARGS ================= +// ================= THREAD ARG ================= struct Args { int* arr; int l; @@ -88,10 +97,8 @@ struct Args { int depth; }; -// forward void parallel_sort(int* arr, int l, int r, int depth); -// ================= THREAD FUNC ================= void* thread_func(void* arg) { Args* a = (Args*)arg; parallel_sort(a->arr, a->l, a->r, a->depth); @@ -113,31 +120,27 @@ void parallel_sort(int* arr, int l, int r, int depth) { pthread_t tid; bool spawned = false; - // ===== ограничение потоков ===== - pthread_mutex_lock(&mutex); + // ===== thread limit control ===== + pthread_mutex_lock(&thread_mutex); if (active_threads < max_threads) { active_threads++; spawned = true; } - pthread_mutex_unlock(&mutex); + pthread_mutex_unlock(&thread_mutex); if (spawned) { - // правая часть → новый поток Args* args = new Args{arr, m + 1, r, depth + 1}; pthread_create(&tid, nullptr, thread_func, args); - // левая → текущий поток parallel_sort(arr, l, m, depth + 1); - // ждём pthread_join(tid, nullptr); - pthread_mutex_lock(&mutex); + pthread_mutex_lock(&thread_mutex); active_threads--; - pthread_mutex_unlock(&mutex); + pthread_mutex_unlock(&thread_mutex); } else { - // без потоков parallel_sort(arr, l, m, depth + 1); parallel_sort(arr, m + 1, r, depth + 1); } @@ -147,13 +150,13 @@ void parallel_sort(int* arr, int l, int r, int depth) { log_end(l, r, depth); } -// ================= UTILS ================= -bool parse_positive_int(const char* value, int& out) { +// ================= UTIL ================= +bool parse_int(const char* s, int& out) { try { - size_t consumed = 0; - int parsed = std::stoi(value, &consumed); - if (value[consumed] != '\0' || parsed < 0) return false; - out = parsed; + size_t p; + int v = std::stoi(s, &p); + if (s[p] != '\0' || v < 0) return false; + out = v; return true; } catch (...) { return false; @@ -164,13 +167,13 @@ bool parse_positive_int(const char* value, int& out) { int main(int argc, char* argv[]) { int n = kDefaultN; - if (argc >= 2 && !parse_positive_int(argv[1], n)) { - std::cerr << "Invalid array size\n"; + if (argc >= 2 && !parse_int(argv[1], n)) { + std::cerr << "Invalid N\n"; return 1; } - if (argc >= 3 && !parse_positive_int(argv[2], max_threads)) { - std::cerr << "Invalid max_threads\n"; + if (argc >= 3 && !parse_int(argv[2], max_threads)) { + std::cerr << "Invalid threads\n"; return 1; } @@ -179,11 +182,11 @@ int main(int argc, char* argv[]) { std::mt19937 rng(std::random_device{}()); std::uniform_int_distribution dist(0, 99999); - for (int i = 0; i < n; ++i) arr[i] = dist(rng); + for (int i = 0; i < n; i++) arr[i] = dist(rng); - std::cout << "Before:\n"; - for (int i = 0; i < std::min(n, kPreviewCount); ++i) - std::cout << arr[i] << ' '; + std::cout << "Before: "; + for (int i = 0; i < std::min(n, kPreviewCount); i++) + std::cout << arr[i] << " "; std::cout << "\n\n"; double t1 = get_time(); @@ -192,10 +195,10 @@ int main(int argc, char* argv[]) { double t2 = get_time(); - std::cout << "\nAfter:\n"; - for (int i = 0; i < std::min(n, kPreviewCount); ++i) - std::cout << arr[i] << ' '; - std::cout << '\n'; + std::cout << "\nAfter: "; + for (int i = 0; i < std::min(n, kPreviewCount); i++) + std::cout << arr[i] << " "; + std::cout << "\n"; std::cout << "\nTime: " << (t2 - t1) << " sec\n"; diff --git a/req.txt b/req.txt index 794cc3d..f089e8e 100644 --- a/req.txt +++ b/req.txt @@ -1 +1,3 @@ openpyxl +matplotlib +PyQt6