-
Notifications
You must be signed in to change notification settings - Fork 0
Сompleted task 3 #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
8f64849
refactor: test directory, use of size_t for sizes
RodionovMaxim05 4adb16e
fix: running tests
RodionovMaxim05 a34bb56
feat: queue-based pipeline processing
RodionovMaxim05 9cb4dae
docs: add docs for pipeline processing functions
RodionovMaxim05 833d767
fix: queue, improve message output
RodionovMaxim05 9eda8c3
tests: add queue benchmark
RodionovMaxim05 a3245d6
tests: add queue benchmarks results
RodionovMaxim05 b594a57
docs: add analysis of queue mode
RodionovMaxim05 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,4 +27,4 @@ jobs: | |
| run: ./scripts/run_clang_tidy.sh | ||
|
|
||
| - name: Test | ||
| run: ./scripts/test.sh | ||
| run: ./scripts/test.sh | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| # Анализ производительности режима очередей (`queue mode`) | ||
|
|
||
| ## Введение | ||
|
|
||
| В рамках данного анализа исследуется эффективность реализации параллельной обработки изображений в архитектуре очередей (`--mode=queue`). В этой модели обработка изображений разбита между тремя типами потоков, которые соединяются очередьми с ограничениями по размеру добавляемого изображения, образуя тем самым конвейер обработки: | ||
| - `readers` - отвечают за чтение исходных данных; | ||
| - `workers` - выполняют применение фильтра `bl`; | ||
| - `writers` - записывают результаты обработки. | ||
|
|
||
| **Конвейер:** | ||
| ``` | ||
| [Reader(s)] → [Input Queue] → [Worker(s)] → [Output Queue] → [Writer(s)] | ||
| ``` | ||
| `Reader` читает изображение и помещает его во входную очередь (`Input Queue`) → `Worker` извлекает изображения из `Input Queue`, выполняет свертку, помещает результат в выходную очередь (`Output Queue`) → `Writer` извлекает результат из `Output Queue` и записывает в файл. | ||
|
|
||
| Тестирование проводилось на наборе из [9 изображений](input_queue_mode/), полученных применением различных фильтров к [`cat.bmp`](images/cat.bmp). Таким образом, все изображения имеют одинаковый размер - `5.9 MiB`, что позволяет минимизировать влияние объёма данных на результаты тестирования. Однако их содержимое различно, поэтому каждое изображение необходимо отдельно загружать в память и записывать результат обратно, в отличие от случая с полностью идентичными изображениями, когда можно было бы загрузить файл один раз и использовать его повторно. | ||
|
|
||
| Также стоит отметить, что расположение мьютексов при работе с условными переменными в конце функциях [`queue_push`](src/queue_mode/queue.c#L111) и [`queue_pop`](src/queue_mode/queue.c#L145) выбрано не случайно. Именно такая организация блокировок позволяет достичь минимального времени выполнения программы. Ключевым моментом является то, что в функции `queue_pop` [`pop_mutex`](src/queue_mode/queue.c#L149) освобождается только после освобождения [`push_mutex`](src/queue_mode/queue.c#L147) при отправке сигнала о появлении свободного места в очереди. Это гарантирует, что поток `worker` сможет раньше начать претендовать на доступ к новым данным из очереди. Если бы `pop_mutex` освобождался раньше, до попытки захвата [`queue_push`](src/queue_mode/queue.c#L145), `worker` оказывался бы в состоянии ожидания освобождения `push_mutex` (которое чаще всего долгое). | ||
|
|
||
| Эксперимент охватывал следующие параметры: | ||
| 1) Конфигурации распределения потоков между ролями: (`readers`, `workers`, `writers`); | ||
| 2) Лимиты памяти : | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А почему было принято решение ограничивать память, а не число изображений в очереди? Так мы можем не угадать и где-нибудь в середине мы неожиданно пропустим какие-то изображения |
||
| - `6 MiB` - одновременно в очереди может находиться только одно изображение; | ||
| - `30 MiB` - до пяти изображений могут быть в очереди; | ||
| - `55 MiB` - очередь позволяет хранить все изображения. | ||
| 3) Число потоков для применения фильтра `bl`: `--thread=2`, `--thread=3`, `--thread=4`, `--thread=5`. | ||
|
|
||
| **Количество прогонов для каждого теста:** 40 (обеспечивает статистическую достоверность результатов). | ||
|
|
||
| **Код бенчмарка**: [`tests/benchmarks/comparison_of_queue_mode.py`](tests/benchmarks/comparison_of_queue_mode.py) | ||
|
|
||
| ## Конфигурация системы: | ||
|
|
||
| - **Процессор:** Процессор: Intel Core i7-11370H (4 физических ядра, 8 логических потоков) с фиксированной частотой 3.3 GHz (`sudo cpupower frequency-set --min 3300MHz --max 3300MHz`); | ||
| - **Кэш L1:** 80 КБ на ядро (48 КБ – кэш данных, 32 КБ – кэш инструкций); | ||
| - **Кэш L2:** 1.25 МБ на ядро; | ||
| - **Общий кэш L3:** 12 МБ. | ||
|
|
||
| - **ОЗУ:** 16ГБ | ||
|
|
||
| - **ОС:** Linux Kubuntu 24.04 | ||
|
|
||
| - **Настройки производительности:** Использовался режим `performance` (`sudo cpupower frequency-set -g performance`) для минимизации влияния динамического изменения частоты процессора. | ||
|
|
||
| Для обеспечения чистоты эксперимента система перезагружалась после каждого тестирования, а сторонние процессы были минимизированы. | ||
|
|
||
| ## Результаты тестирования | ||
|
|
||
| В ходе тестирования измерялось: | ||
| - Общее время выполнения программы; | ||
| - Время работы каждого этапа - чтение, обработка и запись изображения. | ||
|
|
||
| Графики и соответствующие им результаты находятся в папках [`tests/plots/queue_mode_<N>`](tests/plots/), где N обозначает число потоков для применения фильтра. | ||
|
|
||
| ## Анализ результатов | ||
|
|
||
| ### Влияние количества потоков (`--thread`) и `mem_lim` | ||
| - **`--thread=2`**: | ||
| - Наилучшая конфигурация: **1 Reader, 3 Workers, 2 Writers** (`mem_lim=6`, Среднее время - **1.78 сек.**). | ||
| - Увеличение `mem_limit` до 55 MiB ухудшает время. | ||
| - Увеличение общего числа создаваемых потоков (`readers` + `workers` + `writers` + `threads`) сверх 8 не приводит к улучшению производительности, поскольку процессор поддерживает максимум 8 логических потоков. При превышении этого числа возникает конкуренция за вычислительные ресурсы, так как планировщик операционной системы вынужден выполнять частые переключения контекста между потоками. Это увеличивает накладные расходы и ухудшает производительность вместо её повышения. Поэтому в дальнейших тестах суммарное количество потоков намеренно ограничивалось значением 8. | ||
|
|
||
| - **`--thread=3`**: | ||
| - Оптимальная производительность: **1 Reader, 3 Workers, 1 Writer** (`mem_lim=6`, Среднее время - **1.735 сек.**). | ||
| - При увеличении `mem_lim` время также увеличивается. | ||
|
|
||
| - **`--thread=4`**: | ||
| - Лучший результат: **1 Reader, 2 Workers, 1 Writer** (`mem_lim=6`, Среднее время - **1.726 сек.**). | ||
| - При увеличении `mem_lim` время также увеличивается. | ||
|
|
||
| - **`--thread=5`**: | ||
| - Минимальное среднее время: **1.74 сек.** (конфигурация `1-1-1`, `mem_lim=6`). | ||
|
|
||
| **Объяснение:** | ||
|
|
||
| **1.** Результаты показывают, что обработка изображения является узким местом всего pipeline'а. По этой причине увеличение числа потоков, ответственных за применение фильтра, приводит к снижению времени выполнения этого этапа, что в свою очередь положительно влияет на общее время выполнения программы. | ||
|
|
||
| **2.** Во всех рассмотренных случаях наилучшие результаты достигаются при минимальном лимите памяти (**6 MiB**). Увеличение лимита до **30** и **55 MiB** не улучшает, а в большинстве случаев даже его ухудшает. Это объясняется особенностями работы синхронизации между потоками `readers` и `workers` в контексте входной очереди (`Input queue`). При малом лимите памяти (**6 MiB**), очередь позволяет хранить только одно изображение, поэтому читатель вынужден ожидать освобождения места (пока `worker` заберёт это изображение). Это создаёт небольшую задержку для `reader'а`, но позволяет `worker` немедленно приступить к обработке, что особенно важно, поскольку этап обработки является самым медленным звеном pipeline. Напротив, при увеличении лимита памяти, `reader` может загрузить сразу несколько изображений в очередь без ожидания, что повышает вероятность конкуренции за мьютексы (`push_mutex` и `pop_mutex`) между `readers` и `workers`. | ||
| В результате: | ||
| - Рабочие тратят больше времени на ожидание блокировок; | ||
| - Начало обработки первого изображения откладывается; | ||
| - Общее время выполнения программы возрастает. | ||
|
|
||
| Таким образом, ограничение памяти положительно влияет на производительность, так как способствует более раннему началу самого длительного этапа - обработки изображения, минимизируя простои и конкуренцию за общие ресурсы. | ||
|
|
||
| ## Вывод | ||
|
|
||
| Минимальное время выполнения программы зафиксировано при конфигурации `--thread=4`, `1 Reader`, `2 Workers`, `1 Writer`, `mem_lim=6` - среднее время: **1.726 сек.** | ||
|
|
||
| Этот результат демонстрирует, что для достижения максимальной производительности необходимо: | ||
| - Ограничивать размер очереди, чтобы он соответствовал размеру одного изображения. | ||
| - Уменьшить время обработки изображений - найти баланс между ускорением выполнения сверстки (`--thread=4`) и количеством одновременно работающих `worker'ов`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ну хоть бы директорию на полгига прогнать, а то масштабы какие-то детские