bondarenko_max_lab_5 #307
bondarenko_max_lab_5
38
bondarenko_max_lab_5/README.md
Normal file
38
bondarenko_max_lab_5/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Лабораторная работа 5 - Вспоминаем математику или параллельное перемножение матриц
|
||||
### ПИбд-42 || Бондаренко Максим
|
||||
|
||||
# Описание работы
|
||||
|
||||
## Задание
|
||||
> [!NOTE]
|
||||
> Кратко: реализовать умножение двух больших квадратных матриц.
|
||||
>
|
||||
> Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать это в рамках одного алгоритма). В параллельном алгоритме предусмотреть ручное задание количества потоков (число потоков = 1 как раз и реализует задание со *), каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности.
|
||||
|
||||
## Краткое описание модулей и их работа
|
||||
1. matrix.operations.js
|
||||
multiplyMatricesSequential(A, B):
|
||||
- Перебирает элементы матриц и вычисляет их произведение, заполняя результирующую матрицу.
|
||||
multiplyMatricesParallel(A, B, numThreads):
|
||||
- Делит работу между потоками, каждый из которых умножает часть матриц. Запускает воркеры и собирает их результаты.
|
||||
2. benchmark.js
|
||||
generateMatrix(size):
|
||||
- Создает матрицу с случайными значениями заданного размера.
|
||||
benchmark():
|
||||
- Вызывает generateMatrix для создания матриц, затем измеряет время выполнения multiplyMatricesSequential и multiplyMatricesParallel с различными параметрами, выводит результаты.
|
||||
3. matrix.worker.js
|
||||
multiplyPartial(A, B, start, end):
|
||||
- Воркеры выполняют умножение только для части матриц, определенной параметрами start и end, и возвращают частичные результаты через parentPort.
|
||||
|
||||
## Запуск
|
||||
```
|
||||
node benchmark.js
|
||||
```
|
||||
|
||||
## Результат работы
|
||||
> [!IMPORTANT]
|
||||
> ![benchmark.png](./benchmark.png)
|
||||
>
|
||||
> В отчете отражены времена выполнения для каждого из подходов, что позволяет оценить, как число потоков влияет на скорость вычислений для матриц разного размера.
|
||||
|
||||
Ссылка на видео: https://cloud.mail.ru/public/rEGy/HaBwrm7t8
|
29
bondarenko_max_lab_5/benchmark.js
Normal file
29
bondarenko_max_lab_5/benchmark.js
Normal file
@ -0,0 +1,29 @@
|
||||
const { multiplyMatricesSequential, multiplyMatricesParallel } = require('./matrix.operations');
|
||||
|
||||
function generateMatrix(size) {
|
||||
return Array.from({ length: size }, () => Array.from({ length: size }, () => Math.floor(Math.random() * 100)));
|
||||
}
|
||||
|
||||
async function benchmark() {
|
||||
const sizes = [100, 300, 500];
|
||||
const numThreads = [1, 2, 4, 8];
|
||||
|
||||
for (const size of sizes) {
|
||||
const A = generateMatrix(size);
|
||||
const B = generateMatrix(size);
|
||||
|
||||
console.log(`\nMatrix size: ${size}x${size}`);
|
||||
|
||||
console.time(`Sequential (${size}x${size})`);
|
||||
multiplyMatricesSequential(A, B);
|
||||
console.timeEnd(`Sequential (${size}x${size})`);
|
||||
|
||||
for (const threads of numThreads) {
|
||||
console.time(`Parallel (${size}x${size}, ${threads} threads)`);
|
||||
await multiplyMatricesParallel(A, B, threads);
|
||||
console.timeEnd(`Parallel (${size}x${size}, ${threads} threads)`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
benchmark();
|
BIN
bondarenko_max_lab_5/benchmark.png
Normal file
BIN
bondarenko_max_lab_5/benchmark.png
Normal file
Binary file not shown.
After (image error) Size: 52 KiB |
60
bondarenko_max_lab_5/matrix.operations.js
Normal file
60
bondarenko_max_lab_5/matrix.operations.js
Normal file
@ -0,0 +1,60 @@
|
||||
const { Worker } = require('worker_threads');
|
||||
|
||||
function multiplyMatricesSequential(A, B) {
|
||||
const n = A.length;
|
||||
const C = Array.from({ length: n }, () => Array(n).fill(0));
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
for (let j = 0; j < n; j++) {
|
||||
for (let k = 0; k < n; k++) {
|
||||
C[i][j] += A[i][k] * B[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
function multiplyMatricesParallel(A, B, numThreads) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const n = A.length;
|
||||
const step = Math.ceil(n / numThreads);
|
||||
const workers = [];
|
||||
const results = Array.from({ length: numThreads }, () => Array.from({ length: n }, () => Array(n).fill(0)));
|
||||
|
||||
for (let i = 0; i < numThreads; i++) {
|
||||
const start = i * step;
|
||||
const end = Math.min(start + step, n);
|
||||
workers.push(
|
||||
new Promise((res, rej) => {
|
||||
const worker = new Worker('./matrix.worker.js', {
|
||||
workerData: { A, B, start, end }
|
||||
});
|
||||
worker.on('message', result => {
|
||||
results[i] = result;
|
||||
res();
|
||||
});
|
||||
worker.on('error', rej);
|
||||
worker.on('exit', code => {
|
||||
if (code !== 0) rej(new Error(`Worker stopped with exit code ${code}`));
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
Promise.all(workers)
|
||||
.then(() => {
|
||||
const C = Array.from({ length: n }, () => Array(n).fill(0));
|
||||
for (let i = 0; i < numThreads; i++) {
|
||||
for (let j = 0; j < n; j++) {
|
||||
for (let k = 0; k < n; k++) {
|
||||
C[j][k] += results[i][j][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve(C);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { multiplyMatricesSequential, multiplyMatricesParallel };
|
19
bondarenko_max_lab_5/matrix.worker.js
Normal file
19
bondarenko_max_lab_5/matrix.worker.js
Normal file
@ -0,0 +1,19 @@
|
||||
const { parentPort, workerData } = require('worker_threads');
|
||||
|
||||
function multiplyMatricesPart(A, B, start, end) {
|
||||
const n = A.length;
|
||||
const C = Array.from({ length: n }, () => Array(n).fill(0));
|
||||
|
||||
for (let i = start; i < end; ++i) {
|
||||
for (let j = 0; j < n; ++j) {
|
||||
for (let k = 0; k < n; ++k) {
|
||||
C[i][j] += A[i][k] * B[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
const { A, B, start, end } = workerData;
|
||||
const result = multiplyMatricesPart(A, B, start, end);
|
||||
parentPort.postMessage(result);
|
Loading…
Reference in New Issue
Block a user