Files
parallel-programming/lab01_sequential/методичка.md
T
2026-10-07 13:06:47 +05:00

6.7 KiB
Raw Blame History

Лабораторная работа 1. Последовательное вычисление и профилирование

Время на работу: 2 пары.

Цель работы

Создать базовую линию: последовательную реализацию своей задачи и её замеры. Без неё невозможно показать ускорение в следующих лабораторных — нечего будет ускорять.

Теория

Последовательное вычисление

Программа выполняет операцию за операцией, в одном потоке управления. Это простейшая и самая предсказуемая модель: результат не зависит от порядка выполнения, время выполнения = сумма времён всех операций. Все дальнейшие лабораторные сравниваются с этой базой.

Два типа нагрузки

CPU-bound — программа ограничена скоростью процессора: считает, шифрует, сортирует. Время определяется числом элементарных операций.

I/O-bound — программа ограничена ожиданием: сеть, диск, база данных. Время определяется временем ожидания ответов, процессор при этом простаивает.

Отличить просто: если удалить «полезную работу», а программа всё равно медленная — это I/O-bound; если быстрая — CPU-bound. Тип нагрузки определяет, какая модель параллелизма поможет (потоки — для I/O, процессы — для CPU, async — для I/O в больших количествах).

Время: настенное и процессорное

  • time.perf_counter() — «настенные» часы: сколько времени прошло реально (включая сон и ожидание). Ими меряют всё в этом курсе.
  • time.process_time() — только время, потраченное процессором. Разница между ними для I/O-задачи огромна — это её диагноз.

Обе функции монотонные (не откатываются назад, как time.time() при переводе часов), имеют наносекундное разрешение — всегда используйте их, а не time.time().

Профилирование

Профилировщик отвечает на вопрос «где программа проводит время». cProfile собирает статистику по функциям: число вызовов, суммарное время, время без вложенных вызовов.

import cProfile
cProfile.run("main()", sort="cumulative")

Интерпретация: колонка cumtime — общее время функции (с вызовами), totime — собственное. Первые строки обычно сразу показывают узкое место.

Задание

Ваша задача и параметры — по варианту (common/варианты.md), доступ:

from common.tasks import get_variant, TASKS
v = get_variant(13)                      # ваш номер
task = TASKS[v["task_name"]]
data = task["build"](v["cpu_params"])

Заполните solution.py (интерфейсы менять нельзя):

  1. run_cpu_sequential(task_name, params, parts=4) — выполняет задачу последовательно: build → разбиение на parts кусков → kernel для каждого куска в цикле → combine → вернуть checksum. Куски обязательны: в следующих лабораторных те же куски уйдут воркерам.
  2. run_io_sequential(items, delay) — для каждого элемента вызывает common.tasks.io_fetch(item, delay) и собирает результаты в список (в порядке возрастания item).
  3. main() — запускает обе части на параметрах своего варианта, выводит таблицу времен (common.benchmark.make_table) и значения checksum.

Измерения для отчёта

  • CPU-часть: T(1) при разбиении на 1, 2, 4 куска (убедитесь, что checksum одинаков и время почти не меняется — разбиение не должно менять работу).
  • I/O-часть: суммарное время для items из варианта; сравните perf_counter и process_time — увидите, сколько времени машина спит.
  • Профилирование CPU-части: cProfile.run(...), топ-5 функций по времени. Укажите в отчёте, какая функция — узкое место.

Контрольные вопросы

  1. Чем CPU-bound задача отличается от I/O-bound? Какая у вас?
  2. Почему для замеров нужен perf_counter, а не time.time()?
  3. Что показывает cumtime и tototime в выводе cProfile?
  4. Почему checksum не должен зависеть от числа кусков? Что это проверяет?

Что сдаётся

solution.py + отчёт по шаблону: таблицы T(1/2/4 кусков), время I/O-части, сравнение perf_counter/process_time, топ-5 из cProfile, анализ.

Критерии оценки

Пункт Баллы
run_cpu_sequential работает, checksum совпадает при разном разбиении 2
run_io_sequential работает 1
Замеры и сравнение perf_counter/process_time 2
Профилирование и вывод об узком месте 2
Отчёт: таблицы, анализ, ответы на вопросы 3

Типичные ошибки

См. common/типичные_ошибки.md (пп. 8, 9). Здесь их всего две: замеры в отладчике и замеры без повторов.