Init
This commit is contained in:
commit
c394677d07
59 files changed
+5149
No files matched your search
@@ -0,0 +1,111 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Лабораторная работа 4: мультипроцессорный код.
|
||||
|
||||
Заполните функции ниже. ИНТЕРФЕЙСЫ МЕНЯТЬ НЕЛЬЗЯ — по ним работают
|
||||
автотесты (tests/test_lab04.py, запускаются через подпроцесс).
|
||||
|
||||
Запуск из корня курса:
|
||||
python lab04_multiprocessing/solution.py
|
||||
"""
|
||||
import multiprocessing
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||
|
||||
from common.benchmark import make_table, save_speedup_plot, time_call
|
||||
from common.tasks import TASKS, dispatch_kernel, get_variant
|
||||
|
||||
# TODO: впишите свой номер в журнале (1..20)
|
||||
VARIANT_NUMBER = 0
|
||||
|
||||
|
||||
def _sum_list(data):
|
||||
"""Функция уровня модуля — суммирует список (для measure_overhead)."""
|
||||
return sum(data)
|
||||
|
||||
|
||||
def run_cpu_processes(task_name: str, params: dict, p: int):
|
||||
"""CPU-задача на p процессах через Pool и dispatch_kernel.
|
||||
|
||||
Вернуть (checksum, elapsed_seconds). Подсказки:
|
||||
- payload = [(task_name, chunk) для каждого куска];
|
||||
- dispatch_kernel пиккелится, лямбды и вложенные функции — НЕТ;
|
||||
- ctx = multiprocessing.get_context(); with ctx.Pool(p) as pool: ...
|
||||
"""
|
||||
task = TASKS[task_name]
|
||||
# TODO: build -> split -> pool.map(dispatch_kernel, payload) ->
|
||||
# combine -> checksum (замерить время)
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def measure_overhead(items_count_list):
|
||||
"""Стоимость передачи данных процессу.
|
||||
|
||||
Для каждого n из items_count_list: отправить в воркер список из n чисел
|
||||
(list(range(n))), воркер возвращает их сумму (_sum_list). Пул создаётся
|
||||
ОДИН раз, первый вызов — прогрев. Вернуть {n: лучшее_время из 3}.
|
||||
"""
|
||||
# TODO: ctx.Pool(1) -> для каждого n: замер pool.map(_sum_list, [data])
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def main():
|
||||
# --- smoke-режим для автотестов: быстрый прогон и JSON-отчёт -----------
|
||||
# (не удаляйте: тесты запускают solution.py подпроцессом с LAB_SMOKE=1)
|
||||
if os.environ.get("LAB_SMOKE") == "1":
|
||||
from common.tasks import run_sequential, smoke_params
|
||||
name = "integrate" # smoke не зависит от варианта: быстрая задача
|
||||
sp = smoke_params(name)
|
||||
expected, _ = run_sequential(name, sp, parts=1)
|
||||
got, _t = run_cpu_processes(name, sp, p=2)
|
||||
ok = (got == expected) or (isinstance(got, float) and
|
||||
abs(got - expected) < 1e-6 * max(1, abs(expected)))
|
||||
ov = measure_overhead([1_000, 50_000])
|
||||
print("LAB_SMOKE_JSON:" + json.dumps({
|
||||
"ok": True, "result_ok": bool(ok), "p": 2,
|
||||
"overhead": {str(k): t for k, t in ov.items()}}))
|
||||
return
|
||||
|
||||
v = get_variant(VARIANT_NUMBER)
|
||||
print(f"Вариант {v['variant']}: {v['describe']}")
|
||||
print(f"метод запуска: {multiprocessing.get_start_method()}\n")
|
||||
|
||||
# --- T(p) на процессах ---------------------------------------------------
|
||||
rows, times = [], {}
|
||||
expected = None
|
||||
for p in v["p_list"]:
|
||||
t, (cs, _) = time_call(run_cpu_processes,
|
||||
(v["task_name"], v["cpu_params"], p), repeats=2)
|
||||
times[p] = t
|
||||
rows.append((f"процессы, p={p}", t))
|
||||
if expected is None:
|
||||
expected = cs
|
||||
assert cs == expected or (isinstance(cs, float) and
|
||||
abs(cs - expected) < 1e-6 * max(1, abs(expected))), \
|
||||
f"checksum при p={p} не совпал!"
|
||||
print(make_table(rows, title="CPU-задача на процессах"))
|
||||
|
||||
base = times[1]
|
||||
for p, t in times.items():
|
||||
print(f" S(p={p}) = {base / t:.2f}")
|
||||
print()
|
||||
|
||||
# --- Накладные расходы передачи -------------------------------------------
|
||||
overhead = measure_overhead([1_000, 100_000, 1_000_000])
|
||||
print("Стоимость передачи данных процессу (туда+обратно):")
|
||||
for n, t in sorted(overhead.items()):
|
||||
print(f" {n:>9,} чисел: {t * 1000:8.1f} мс".replace(",", " "))
|
||||
|
||||
save_speedup_plot({"процессы": sorted(times.items())},
|
||||
f"Ускорение CPU-задачи процессами ({v['describe']})",
|
||||
os.path.join(os.path.dirname(__file__), "speedup.png"))
|
||||
|
||||
# TODO: в отчёт — S(p) и число физических ядер вашей машины,
|
||||
# сравните время kernel варианта со временем передачи из measure_overhead.
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user