This commit is contained in:
lovinervy committed 2026-10-07 13:06:47 +05:00
commit c394677d07
59 files changed
+5149

No files matched your search

+110
View File
@@ -0,0 +1,110 @@
# Лабораторная работа 7. Сравнительный анализ: одна задача — четыре подхода
**Время на работу:** 2 пары. **Зависимости:** лабы 1–6. Итоговая работа.
## Цель работы
Свести весь курс в одну таблицу: ваша CPU-задача и ваша I/O-нагрузка,
выполненные последовательно, потоками, процессами и асинхронно. Объяснить
каждую цифру. Это работа для защиты: по ней проверяется понимание всего
курса.
## Теория
### Ускорение и эффективность
- Ускорение: **S(p) = T(1) / T(p)** — во сколько раз быстрее на p воркерах.
- Эффективность: **E(p) = S(p) / p** — насколько эффективно используется
каждый воркер. E = 1 — идеал, E = 0.5 — половина мощности простаивает.
### Закон Амдала
Если доля последовательного кода задачи равна s (0 ≤ s ≤ 1), то ускорение
ограничено:
```
S(p) ≤ 1 / (s + (1 − s) / p)
```
При s = 0.1 и p → ∞: S ≤ 10. Даже бесконечное число воркеров не даст
больше 10×. Отсюда главный вывод курса: **сначала сокращайте
последовательную часть и накладные расходы, потом наращивайте p.**
В `common.benchmark` есть `amdahl(s, p)` — сравните свои S(p) с теорией:
зная измеренное S(p), можно оценить эффективную долю последовательной части
вашего эксперимента (создание пулов, pickle, GIL-переключения — всё это
«последовательная» часть).
### Матрица выбора модели
| Задача | Потоки | Процессы | asyncio |
|---|---|---|---|
| CPU-bound (чистый Python) | ✗ (GIL) | ✓ | ✗ (блокирует loop) |
| CPU-bound в C-коде (hashlib, numpy) | ✓ | ✓ | ✗ |
| I/O-bound, десятки задач | ✓ | возможно (дорого) | ✓ |
| I/O-bound, тысячи задач | дорого | ✗ | ✓✓ |
## Задание
Заполните `solution.py` — оба сценария из ваших лабораторных:
**CPU-сценарий** (задача из варианта):
1. `cpu_sequential(task_name, params)` — как в лабе 1;
2. `cpu_threads(task_name, params, p)` — как в лабе 3 (S ≈ 1!);
3. `cpu_processes(task_name, params, p)` — как в лабе 4 (S ≈ ядра).
**I/O-сценарий** (items × delay из варианта):
4. `io_sequential(items, delay)` — как в лабе 1;
5. `io_threads(items, delay, p)` — как в лабе 2;
6. `io_async(items, delay)` — как в лабе 6;
7. `io_async_limited(items, delay, max_concurrent)` — с семафором 8.
**`main()`** — таблицы для обоих сценариев с T(p), S(p), E(p); два графика
ускорения; оценка доли s по закону Амдала для процессов.
### Ожидаемые результаты (сверьтесь)
CPU: потоки S ≈ 1; процессы S(p) ≈ до числа физических ядер.
I/O: последовательный — база; потоки и async — S ≈ p; async без лимита —
минимальное время (нет расходов на потоки); processes для I/O — работает,
но с заметными накладными расходами.
### Что дополнительно оценить
- Разница T(1) у процессов против последовательного — цена старта процессов
и pickle.
- По S(p_max) процессов найдите s через `amdahl` (подберите s так, чтобы
теория совпала с практикой) — укажите его в отчёте.
## Контрольные вопросы
1. Почему потоки не ускорили CPU-задачу, но ускорили I/O?
2. Почему asyncio на I/O обгоняет потоки? Откуда выигрыш?
3. Какая доля последовательного кода получилась у процессов по Амдалу?
Что в неё входит?
4. Какую модель вы выбрали бы для веб-краулера на 10 000 страниц?
Для рендера видео? Обоснуйте.
5. Что в ваших замерах не совпало с теорией и почему?
## Что сдаётся
`solution.py` + отчёт: две таблицы (CPU и I/O) с T/S/E, два графика,
оценка s по Амдалу, развёрнутые выводы (это итоговая работа — выводы
должны покрывать весь курс), ответы на вопросы.
## Критерии оценки
| Пункт | Баллы |
|---|---|
| Все 7 функций работают, checksum корректен | 3 |
| Таблицы и графики для обоих сценариев | 3 |
| Оценка s по закону Амдала с объяснением | 2 |
| Выводы и ответы на вопросы (защита) | 4 |
## Типичные ошибки
- Сравнение T(p) разных сценариев при разном объёме работы — объём
фиксирован внутри сценария.
- Забыт smoke-режим `LAB_SMOKE` (автотесты запускают solution.py
подпроцессом — не удаляйте блок в main()).
- Замеры в один запуск без повторов: `time_call(..., repeats=3)`.