1 Commits

Author SHA1 Message Date
dd2cdc1130 Lab-2 2024-01-06 23:35:43 +04:00
18 changed files with 285 additions and 257 deletions

View File

@@ -0,0 +1,2 @@
*/*/bin
*/*/obj

View File

@@ -1,7 +1,7 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
@@ -93,6 +93,7 @@ StyleCopReport.xml
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
@@ -296,6 +297,17 @@ node_modules/
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
@@ -352,6 +364,9 @@ ASALocalRun/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
@@ -364,6 +379,27 @@ MigrationBackup/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
##
## Visual studio for Mac
##
@@ -439,16 +475,3 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
# JetBrains Rider
.idea/
*.sln.iml
##
## Visual Studio Code
##
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

View File

@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "worker-1", "worker-1\worker-1.csproj", "{1B2479E1-B738-43B3-BD2E-0A8E0A72081D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "worker-2", "worker-2\worker-2.csproj", "{0F8A06E1-9249-412F-886F-8C0D24057473}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1B2479E1-B738-43B3-BD2E-0A8E0A72081D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B2479E1-B738-43B3-BD2E-0A8E0A72081D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B2479E1-B738-43B3-BD2E-0A8E0A72081D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B2479E1-B738-43B3-BD2E-0A8E0A72081D}.Release|Any CPU.Build.0 = Release|Any CPU
{0F8A06E1-9249-412F-886F-8C0D24057473}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F8A06E1-9249-412F-886F-8C0D24057473}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F8A06E1-9249-412F-886F-8C0D24057473}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F8A06E1-9249-412F-886F-8C0D24057473}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,54 @@
# Отчёт по лабораторной работе №2
Выполнил: студент гр. ИСЭбд-41 Михайлов Юрий.
Задание программы 1: Ищет в каталоге /var/data самый большой по объёму файл и перекладывает его в /var/result/data.txt.
Задание программы 2: Ищет набольшее число из файла /var/data/data.txt и сохраняет его вторую степень в /var/result/result.txt.
# Создание приложений
Создаем 2 приложения с помощью команды:
```yam
dotnet new console -o worker-1
dotnet new console -o worker-2
```
Пр№ 1: Ищет в каталоге /var/data самый большой по объёму файл и перекладывает его в /var/result/data.txt.
[Текст программы worker-1](worker-1/Program.cs)
Пр№ 2: Ищет набольшее число из файла /var/data/data.txt и сохраняет его вторую степень в /var/result/result.txt.
[Текст программы worker-2](worker-2/Program.cs)
Cоздали файл [.gitignore](.gitignore) с помощью команды dotnet new gitignore.
# Настройка окуржения
Для обеспечения взаимодействия между двумя приложениями мы применили следующий подход:
Для каждого приложения были разработаны файлы Dockerfile ([программа 1](worker-1/Dockerfile), [программа 2](worker-1/Dockerfile)) с подробным описанием процесса сборки.
Также был создан файл [docker-compose.yml](docker-compose.yml), в котором указан манифест для запуска распределённого приложения.
Также был создан файл [.dockerignore](.dockerignore) и дополнен [.gitignore](.gitignore), чтобы исключить для сборки и коммита всё лишнее.
# Сборка и запуск
В каталог ./data помещены 2 файла: another_data.txt и data.txt.
Для запуска приложения необходимо ввести команду `docker compose up --build`.
Результат запуска после сборки:
```
[+] Running 3/3
✔ Network lab_2_default Created 0.1s
✔ Container lab_2-worker-1-1 Created 0.1s
✔ Container lab_2-worker-2-1 Created 0.1s
Attaching to lab_2-worker-1-1, lab_2-worker-2-1
lab_2-worker-1-1 | Файл перемещен.
lab_2-worker-1-1 exited with code 0
lab_2-worker-2-1 | Мax число из файла: 14
lab_2-worker-2-1 | Вторая стпень Max числа: 196
lab_2-worker-2-1 exited with code 0
```
В результате 1 работы в каталоге `./result` создался файл `data.txt`.
В результате 2 работы в каталоге `./result` создался файл `result.txt` с содержимым `196`, что соответствует входным данным.

View File

@@ -0,0 +1,5 @@
10
10
10
10
10

View File

@@ -0,0 +1,14 @@
1
2
3
4
5
6
7
8
9
10
11
12
13
14

View File

@@ -0,0 +1,13 @@
version: "3.1"
services:
worker-1:
build: ./worker-1
volumes:
- ./data:/var/data
- ./result:/var/result
worker-2:
build: ./worker-2
volumes:
- ./result:/var/result
depends_on:
- worker-1

View File

@@ -0,0 +1,14 @@
1
2
3
4
5
6
7
8
9
10
11
12
13
14

View File

@@ -0,0 +1 @@
196

View File

@@ -0,0 +1,17 @@
#задаем базовый образ на .net 6.0
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
#задаем рабочую директорию
WORKDIR /app
#в каталог копируем файлы и папки в контейнер
COPY . /app
#создаем образы и устанавливаем данные пакеты в контейнер
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /publish
FROM mcr.microsoft.com/dotnet/aspnet:6.0 as runtime
WORKDIR /publish
COPY --from=build-env /publish .
#вызываем приложение во время выполнения контейнера
ENTRYPOINT ["dotnet", "worker-1.dll"]

View File

@@ -0,0 +1,37 @@

using System;
using System.IO;
using System.Text;
string[] files = Directory.GetFiles("../var/data");
string maxFilePath = "";
long maxFileSize = 0;
foreach (var filePath in files)
{
FileInfo fileInfo = new FileInfo(filePath);
if (fileInfo.Length > maxFileSize)
{
maxFileSize = fileInfo.Length;
maxFilePath = filePath;
}
}
using (FileStream sourceStream = File.OpenRead(maxFilePath))
{
byte[] buffer = new byte[sourceStream.Length];
await sourceStream.ReadAsync(buffer, 0, buffer.Length);
string text = Encoding.Default.GetString(buffer);
using (FileStream targetStream = new FileStream("../var/result/data.txt", FileMode.OpenOrCreate))
{
targetStream.SetLength(0);
byte[] textBytes = Encoding.Default.GetBytes(text);
await targetStream.WriteAsync(textBytes, 0, textBytes.Length);
}
}
Console.WriteLine("Файл перемещен.");

View File

@@ -3,12 +3,9 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>worker_1</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.11" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,17 @@
#задаем базовый образ на .net 6.0
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
#задаем рабочую директорию
WORKDIR /src
#в каталог копируем файлы и папки в контейнер
COPY . ./
#создаем образы и устанавливаем данные пакеты в контейнер
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /publish
FROM mcr.microsoft.com/dotnet/aspnet:6.0 as runtime
WORKDIR /publish
COPY --from=build-env /publish .
#вызываем приложение во время выполнения контейнера
ENTRYPOINT ["dotnet", "worker-2.dll"]

View File

@@ -0,0 +1,34 @@
 using System;
using System.IO;
using System.Text;
string[] numbers;
using (FileStream fstream = File.OpenRead("/var/result/data.txt"))
{
byte[] buffer = new byte[fstream.Length];
await fstream.ReadAsync(buffer, 0, buffer.Length);
string text = Encoding.Default.GetString(buffer);
text = text.Replace("\r\n", ";");
numbers = text.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
}
int maxNumber = int.MinValue;
foreach (var number in numbers)
{
int currentNumber = Convert.ToInt32(number);
if (currentNumber > maxNumber)
{
maxNumber = currentNumber;
}
}
int maxNumberSquared = maxNumber * maxNumber;
using (FileStream fstream = new FileStream("/var/result/result.txt", FileMode.OpenOrCreate))
{
byte[] buffer = Encoding.Default.GetBytes(maxNumberSquared.ToString());
await fstream.WriteAsync(buffer, 0, buffer.Length);
}
Console.WriteLine("Мax число из файла: " + maxNumber);
Console.WriteLine("Вторая степень Max числа: " + maxNumberSquared);

View File

@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>worker_2</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -1,173 +0,0 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
public class MatrixMultiplication
{
public static int[][] MultiplySequential(int[][] matrixA, int[][] matrixB)
{
int rowsA = matrixA.Length;
int colsA = matrixA[0].Length;
int colsB = matrixB[0].Length;
int[][] result = new int[rowsA][];
for (int i = 0; i < rowsA; i++)
{
result[i] = new int[colsB];
for (int j = 0; j < colsB; j++)
{
for (int k = 0; k < colsA; k++)
{
result[i][j] += matrixA[i][k] * matrixB[k][j];
}
}
}
return result;
}
public static int[][] MultiplyParallel(int[][] matrixA, int[][] matrixB, int numThreads)
{
int rowsA = matrixA.Length;
int colsA = matrixA[0].Length;
int colsB = matrixB[0].Length;
int[][] result = new int[rowsA][];
Parallel.For(0, rowsA, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, i =>
{
result[i] = new int[colsB];
for (int j = 0; j < colsB; j++)
{
for (int k = 0; k < colsA; k++)
{
result[i][j] += matrixA[i][k] * matrixB[k][j];
}
}
});
return result;
}
[Benchmark]
public void MultiplySequential_100x100()
{
int[][] matrixA = GenerateRandomMatrix(100, 100);
int[][] matrixB = GenerateRandomMatrix(100, 100);
MultiplySequential(matrixA, matrixB);
}
[Benchmark]
public void MultiplyParallel_100x100_4TH()
{
int[][] matrixA = GenerateRandomMatrix(100, 100);
int[][] matrixB = GenerateRandomMatrix(100, 100);
MultiplyParallel(matrixA, matrixB, 4);
}
[Benchmark]
public void MultiplyParallel_100x100_8TH()
{
int[][] matrixA = GenerateRandomMatrix(100, 100);
int[][] matrixB = GenerateRandomMatrix(100, 100);
MultiplyParallel(matrixA, matrixB, 8);
}
[Benchmark]
public void MultiplyParallel_100x100_16TH()
{
int[][] matrixA = GenerateRandomMatrix(100, 100);
int[][] matrixB = GenerateRandomMatrix(100, 100);
MultiplyParallel(matrixA, matrixB, 16);
}
[Benchmark]
public void MultiplySequential_300x300()
{
int[][] matrixA = GenerateRandomMatrix(300, 300);
int[][] matrixB = GenerateRandomMatrix(300, 300);
MultiplySequential(matrixA, matrixB);
}
[Benchmark]
public void MultiplyParallel_300x300_4TH()
{
int[][] matrixA = GenerateRandomMatrix(300, 300);
int[][] matrixB = GenerateRandomMatrix(300, 300);
MultiplyParallel(matrixA, matrixB, 4);
}
[Benchmark]
public void MultiplyParallel_300x300_8TH()
{
int[][] matrixA = GenerateRandomMatrix(300, 300);
int[][] matrixB = GenerateRandomMatrix(300, 300);
MultiplyParallel(matrixA, matrixB, 8);
}
[Benchmark]
public void MultiplyParallel_300x300_16TH()
{
int[][] matrixA = GenerateRandomMatrix(300, 300);
int[][] matrixB = GenerateRandomMatrix(300, 300);
MultiplyParallel(matrixA, matrixB, 16);
}
[Benchmark]
public void MultiplySequential_500x500()
{
int[][] matrixA = GenerateRandomMatrix(500, 500);
int[][] matrixB = GenerateRandomMatrix(500, 500);
MultiplySequential(matrixA, matrixB);
}
[Benchmark]
public void MultiplyParallel_500x500_4TH()
{
int[][] matrixA = GenerateRandomMatrix(500, 500);
int[][] matrixB = GenerateRandomMatrix(500, 500);
MultiplyParallel(matrixA, matrixB, 4);
}
[Benchmark]
public void MultiplyParallel_500x500_8TH()
{
int[][] matrixA = GenerateRandomMatrix(500, 500);
int[][] matrixB = GenerateRandomMatrix(500, 500);
MultiplyParallel(matrixA, matrixB, 8);
}
[Benchmark]
public void MultiplyParallel_500x500_16TH()
{
int[][] matrixA = GenerateRandomMatrix(500, 500);
int[][] matrixB = GenerateRandomMatrix(500, 500);
MultiplyParallel(matrixA, matrixB, 16);
}
private static int[][] GenerateRandomMatrix(int rows, int cols)
{
int[][] matrix = new int[rows][];
Random rand = new Random();
for (int i = 0; i < rows; i++)
{
matrix[i] = new int[cols];
for (int j = 0; j < cols; j++)
{
matrix[i][j] = rand.Next(1, 10);
}
}
return matrix;
}
}
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<MatrixMultiplication>();
Console.ReadLine();
}
}

View File

@@ -1,66 +0,0 @@
# Отчёт по лабораторной работе №5
Выполнил: студент гр. ИСЭбд-41 Михайлов Ю.С.
## Запуск приложения
Было выбрано консольное приложение, язык программирования - C#.
Перемножение матриц обычным алгоритмом:
```
public static int[][] MultiplySequential(int[][] matrixA, int[][] matrixB)
{
int rowsA = matrixA.Length;
int colsA = matrixA[0].Length;
int colsB = matrixB[0].Length;
int[][] result = new int[rowsA][];
for (int i = 0; i < rowsA; i++)
{
result[i] = new int[colsB];
for (int j = 0; j < colsB; j++)
{
for (int k = 0; k < colsA; k++)
{
result[i][j] += matrixA[i][k] * matrixB[k][j];
}
}
}
return result;
}
```
Перемножение матриц параллельным алгоритмом:
```
public static int[][] MultiplyParallel(int[][] matrixA, int[][] matrixB, int numThreads)
{
int rowsA = matrixA.Length;
int colsA = matrixA[0].Length;
int colsB = matrixB[0].Length;
int[][] result = new int[rowsA][];
Parallel.For(0, rowsA, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, i =>
{
result[i] = new int[colsB];
for (int j = 0; j < colsB; j++)
{
for (int k = 0; k < colsA; k++)
{
result[i][j] += matrixA[i][k] * matrixB[k][j];
}
}
});
return result;
}
```
## Результаты
![](pic.PNG)
Вывод: если в матрице не слишком много элементов, обычный алгоритм работает быстрее. Параллельный алгоритм следует использовать для обработки большого количества данных. В сравнении с однопоточным алгоритмом, работа параллельного в несколько раз быстрее.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB