Init
This commit is contained in:
commit
c394677d07
59 files changed
+5149
No files matched your search
@@ -0,0 +1,100 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Лабораторная работа 1: последовательное вычисление и профилирование.
|
||||
|
||||
Заполните функции ниже. ИНТЕРФЕЙСЫ МЕНЯТЬ НЕЛЬЗЯ — по ним работают
|
||||
автотесты (tests/test_lab01.py).
|
||||
|
||||
Запуск из корня курса:
|
||||
python lab01_sequential/solution.py
|
||||
"""
|
||||
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, time_call
|
||||
from common.tasks import TASKS, get_variant, io_fetch
|
||||
|
||||
# TODO: впишите свой номер в журнале (1..20)
|
||||
VARIANT_NUMBER = 0
|
||||
|
||||
|
||||
def run_cpu_sequential(task_name: str, params: dict, parts: int = 4):
|
||||
"""Последовательное выполнение задачи из `parts` кусков.
|
||||
|
||||
Возвращает (checksum, elapsed_seconds).
|
||||
|
||||
Схема:
|
||||
build -> split -> kernel (по очереди!) -> combine -> checksum
|
||||
"""
|
||||
task = TASKS[task_name]
|
||||
# TODO: реализуйте по схеме выше и замерьте время perf_counter-ом
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def run_io_sequential(items: int, delay: float = 0.05):
|
||||
"""Последовательное выполнение I/O-нагрузки.
|
||||
|
||||
Для каждого item из range(items) вызывает io_fetch(item, delay).
|
||||
Возвращает (список_результатов, elapsed_seconds).
|
||||
Результаты — в порядке возрастания item.
|
||||
"""
|
||||
# TODO: цикл по items, сбор результатов, замер времени
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def main():
|
||||
v = get_variant(VARIANT_NUMBER)
|
||||
print(f"Вариант {v['variant']}: {v['describe']}")
|
||||
print(f"I/O-нагрузка: {v['io']['items']} запросов по {v['io']['delay']} c\n")
|
||||
|
||||
# --- CPU-часть: T(1), T(2), T(4) --------------------------------------
|
||||
rows, checksums = [], []
|
||||
for parts in (1, 2, 4):
|
||||
t, (cs, _) = time_call(run_cpu_sequential,
|
||||
(v["task_name"], v["cpu_params"], parts))
|
||||
rows.append((f"CPU, {parts} кусков", t))
|
||||
checksums.append(cs)
|
||||
print(make_table(rows, title="CPU-часть (последовательно)"))
|
||||
|
||||
def same(a, b):
|
||||
# float-результаты сравниваем с допуском (порядок суммирования!)
|
||||
if isinstance(a, float) or isinstance(b, float):
|
||||
return abs(a - b) <= 1e-6 * max(1.0, abs(a))
|
||||
return a == b
|
||||
|
||||
ok = all(same(checksums[0], c) for c in checksums[1:])
|
||||
print(f"checksum совпадает при разном разбиении: {ok}\n")
|
||||
|
||||
# --- I/O-часть ----------------------------------------------------------
|
||||
results, t_io = run_io_sequential(v["io"]["items"], v["io"]["delay"])
|
||||
t0 = time.perf_counter()
|
||||
c0 = time.process_time()
|
||||
run_io_sequential(v["io"]["items"], v["io"]["delay"])
|
||||
wall = time.perf_counter() - t0
|
||||
proc = time.process_time() - c0
|
||||
print(f"I/O-часть: {len(results)} запросов за {t_io:.3f} c")
|
||||
print(f" настенное время (perf_counter): {wall:.3f} c")
|
||||
print(f" процессорное время (process_time): {proc:.3f} c")
|
||||
print(f" доля ожидания: {100 * (1 - proc / wall):.0f}%")
|
||||
print(f" потенциал ускорения потоками (лаба 2): x{t_io / v['io']['delay']:.1f}\n")
|
||||
|
||||
# --- Профилирование ------------------------------------------------------
|
||||
import cProfile
|
||||
import io as _io
|
||||
import pstats
|
||||
|
||||
print("--- cProfile CPU-части (топ-5 по времени) ---")
|
||||
profiler = cProfile.Profile()
|
||||
profiler.enable()
|
||||
run_cpu_sequential(v["task_name"], v["cpu_params"], parts=4)
|
||||
profiler.disable()
|
||||
stream = _io.StringIO()
|
||||
pstats.Stats(profiler, stream=stream).sort_stats("cumulative").print_stats(5)
|
||||
print(stream.getvalue())
|
||||
# TODO: выпишите в отчёт, какая функция — узкое место
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user