Implementation of the matrix-vector multiplication algorithm using the MPI library (Message Passing Interface)
Task: implement 3 algorithms for multiplying a matrix by a vector:
- When splitting by lines
- When divided into columns
- With block partitioning
- The number of executing processes is less than or a multiple of the number of physical CPU cores.
double
- The size of the matrix for consistency of experiments in each dimension is a multiple of each value of the number of executing processes
-
The size of the vector is equal to the second dimension of the matrix (the number of columns of the matrix). That is, if the size of the matrix is
$(24*48)$ , then the length of the vector will be$48$ .
Data generation was performed using the Python library
numpy, followed by saving the values ofdoublein the format%.4fin terms of C language specifiers to a text file.
The matrices for performing calculations are square in order to preserve the total amount of data for each Process of a distributed system.
As a result of the algorithms, a vector of type double of the size of the first dimension of the matrix (the number of its rows) is expected, that is,
The following metrics were used to evaluate the performance of the algorithms
-
Execution time. Conditions:
- At the beginning of the operation time measurement, the algorithm has preloaded Matrix and Vector data on the main process.
- Completion of the work time measurement occurs when the main process has received the final vector
$\textemdash$ The result of multiplying the matrix by the vector. - The running time was measured independently on each process and was subsequently aggregated using the
maxfunction.
-
Speed Up (Acceleration)
- It is calculated as a quotient of the execution time on one process and on
nprocesses.$$S = \frac{T_{serial}}{T_{parallel}}$$
- It is calculated as a quotient of the execution time on one process and on
-
Efficiency (Efficiency)
- Let
S$\textemdash$ be the acceleration, andp$\textemdash$ be the number of processes. Then the efficiency is calculated as a quotient of the acceleration and the number of processes.$$E = \frac{S}{p} = \frac{T_{serial}}{p * T_{parallel}}$$
- Let
Averaging of 100 experiments was used for measurement accuracy in each experiment
- CPU: Intel(R) Core(TM) i5-10400F CPU @ 2.90GHz 2.90 GHz. | Cores: 6 | Hyper Threading
- RAM: 32.0 GB
- OS: WSL Ubuntu 22.04.3 LTS
- The more data there is, the more noticeable the decrease in work time
- Processes up to the 6th (for 6 physical processor cores) are "useful". With further increase (up to 12) ** execution time increases moderately (for small amounts of data) and increases dramatically for any amount of data when increasing processes to 24. The reason for
$\textemdash$ is the overhead of interprocess communication. - Acceleration maximum for 6 processes (for 6 physical cores).
- The worst acceleration is when there is extremely little data for each process.
- Acceleration behaves the same for a larger proportion of datasets.
- Efficiency decreases exponentially depending on the number of processes.
- The least efficiency
$\textemdash$ when dividing a small task into many Workers.
- The minimum execution time corresponds to 6 processes (for 6 physical CPU cores).
- The minimum data set has one of the best speedups for all processes.
- The best result of time on 12 processes (for 6 physical cores) with a large amount of data. The multithreading of the processor turns out to be useful.
- The value of efficiency and acceleration is better when divided into Columns under all conditions, however execution time is much worse than that of other algorithms.
- The shortest time is achieved using a Block Division algorithm.
- When divided into Columns depending on the amount of data acceleration and efficiency is 2-4 times better with 24 processes and 2 times better with 6 active processes (by 6 physical processor cores).




