# Распределенные вычисления и приложения Л5

## _Автор Базунов Андрей Игревич ПИбд-42_

---
> ### Задание
> - Кратко: реализовать умножение двух больших квадратных матриц.
> - Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать
    это в рамках одного алгоритма). В параллельном алгоритме предусмотреть ручное задание количества потоков (число
    потоков = 1 как раз и реализует задание со *), каждый из которых будет выполнять умножение элементов матрицы в
    рамках своей зоны ответственности.
---

## Алгоритм умножения:

### Функция умножения строки на столбец

<details>
<summary>Код</summary>

```python
def mul_row_and_column_in_thread(queue: _QUEUE_TYPE) -> list[tuple[int | float, int]]:
    result = []
    while queue.qsize():
        local_result = 0
        row, column, place = queue.get()
        for k in range(len(row)):
            local_result += row[k] * column[k]
        result.append((local_result, place))

    return result
```

</details>

### Функция распределения вычислений между процессами и сборки результатов в матрицу

<details>
<summary>Код</summary>

```python
def mul_matrixs(m1: Matrix, m2: Matrix, threads: int = 0):
    if m1.size != m2.size:
        return None

    if threads == 0:
        threads = 1

    result = Matrix(size=m1.size, suplyer=0)

    thread_queues = [Queue() for _ in range(threads)]
    thread_iterator = 0

    for row_m1, column_m2 in itertools.product(m1.rows, m2.columns):
        thread_queues[thread_iterator].put((row_m1, column_m2, thread_iterator))
        thread_iterator += 1
        if thread_iterator >= threads:
            thread_iterator = 0

    with ThreadPoolExecutor(max_workers=threads) as executor:
        flat = []

        for item in executor.map(mul_row_and_column_in_thread, thread_queues):
            flat += item

        flat.sort(key=lambda x: x[1])
        result.from_flat([*map(lambda x: x[0], flat)])

    return result
```

</details>

| Размер матрицы | 1 Поток (сек) | 5 Потоков (сек) | 20 Потоков (сек) |
|----------------|---------------|-----------------|------------------|
| 50x50          | 0.00654       | 0.00666         | 0.00685          |
| 100x100        | 0.03809       | 0.03753         | 0.03796          |
| 150x150        | 0.11277       | 0.11239         | 0.11342          |
| 200x200        | 0.24218       | 0.2474          | 0.25167          |
| 250x250        | 0.45891       | 0.46111         | 0.46475          |
| 300x300        | 0.80544       | 0.81466         | 0.8198           |
| 350x350        | 1.28701       | 1.30309         | 1.32854          |
| 400x400        | 1.93252       | 1.97905         | 2.00756          |
| 450x450        | 2.81152       | 2.88893         | 2.94218          |
| 500x500        | 3.87053       | 4.02238         | 4.03649          |
| 550x550        | 5.26902       | 5.43371         | 6.10302          |
| 600x600        | 6.82189       | 7.09791         | 7.17916          |
| 650x650        | 8.80005       | 9.15325         | 11.26757         |
| 700x700        | 11.04467      | 11.50241        | 12.2389          |
| 750x750        | 13.50451      | 14.23333        | 18.4895          |
| 800x800        | 16.5745       | 17.30878        | 20.61224         |
| 850x850        | 19.99281      | 23.19894        | 30.13554         |
| 900x900        | 23.48408      | 24.84928        | 31.74338         |
| 950x950        | 27.84541      | 29.19429        | 41.40166         |
| 1000x1000      | 32.5547       | 34.0334         | 44.55267         |