Работа с библиотекой. Название работа с динамической библиотекой dll
Скачать 1.04 Mb.
|
Отчёт №2. Выполнила студентка 2-ого курса 2.1. ПМИ (б) – Русьянова Саша. Название – работа с динамической библиотекой dll. 1. Постановка задачи. Создать программу, которая выполняет следующие функции: - Сложение и умножение двумерных матриц без использования динамической библиотеки; - Сложение и умножение двумерных матриц посредством динамической библиотеки с использованием С++; - Сложение двумерных матриц посредством динамической библиотеки с использованием XMM регистров; - Сравнение времени, затраченного на выполнение указанных выше действий. 2. Математическая модель. Умножение и сложение двумерных массивов в данной программе происходит с помощью функций конвертации двумерного массива в одномерный и наоборот. То есть двумерные массивы конвертируются в одномерные, происходит их сложение или умножение, а затем полученный одномерный массив конвертируется обратно в двумерный. Создание динамической библиотеки происходит следующим образом: решение – добавить – пустой проект, затем открываем свойства выбранного проекта и меняем тип конфигурации на «Динамическая библиотека dll», затем нажимаем правой кнопкой на этот проект – добавить – создать элемент – код – файл С++. В созданном файле пишем алгоритм сложения или умножения одномерных массивов на языке С++, а затем на языке ассемблера. 3. Описание интерфейса. Окно программы содержит 6 кнопок: - «Сгенерировать массивы», по нажатию на эту кнопку происходит инициализация массивов в соответствии с указанной размерностью и отображение массивов в сетки; - «Сложить массивы (С#)”, по нажатию на эту кнопку происходит сложение массивов без использования динамической библиотеки и отображение результата в сетку; - «Умножить массивы (С#)”, по нажатию на эту кнопку происходит умножение массивов без использования динамической библиотеки и отображение результата в сетку; - «Сложить массивы (С++)”, по нажатию на эту кнопку происходит сложение массивов посредством динамической библиотеки с использованием С++; - «Умножить массивы (С++)”, по нажатию на эту кнопку происходит умножение массивов посредством динамической библиотеки с использованием С++; -«Сложить массивы (Xmm)”, по нажатию на эту кнопку происходит сложение массивов посредством динамической библиотеки с использованием Xmm регистров. Также окно программы содержит 9 сеток для отображение сгенерированных массивов и результатов их сложения\умножения. Интерфейс программы включает в себя окно для ввода размерности двумерных массивов. 4. Описание программы с кодом. using System; using System.Diagnostics; using System.Windows.Forms; using System.Linq; namespace Работа_с_библиотеками { class CshCom { CshDll CD = new CshDll(); int[,] ArrayA; int[,] ArrayB; int[,] ArrayRes; int[] ArA; int[] ArB; int[] ArRes; int N = 0; public void Gen(Int32 n1) { N = n1; ArrayA = new int[n1, n1]; ArrayB = new int[n1, n1]; ArrayRes = new int[n1, n1]; ArA = new int[n1 * n1]; ArB = new int[n1 * n1]; ArRes = new int[n1 * n1]; Random rand = new Random(); for (int i = 0; i < n1; i++) for (int j = 0; j < n1; j++) { ArrayA[i, j] = (int)rand.Next(0, 100); ArrayB[i, j] = (int)rand.Next(0, 100); } } public void Show(DataGridView _A, DataGridView _B, Int32 n1) { N = n1; _A.RowCount = n1; _A.ColumnCount = n1; _B.RowCount = n1; _B.ColumnCount = n1; for (int i = 0; i < n1; i++) for (int j = 0; j < n1; j++) { _A.Rows[i].Cells[j].Value = ArrayA[i, j]; _B.Rows[i].Cells[j].Value = ArrayB[i, j]; } } public void AddCs(Label _time, DataGridView _Res) { if (ArrayA == null && ArrayB == null) { MessageBox.Show("Массивы не заданы!"); } try { _Res.RowCount = N; _Res.ColumnCount = N; Stopwatch timer = new Stopwatch(); ArA = ConvertTo1(ArrayA, ArA); ArB = ConvertTo1(ArrayB, ArB); timer.Start(); for (int i = 0; i < N * N; i++) { ArRes[i] = ArA[i] + ArB[i]; } timer.Stop(); _time.Text = timer.Elapsed.ToString(); ArrayRes = ConvertTo2(ArRes, ArrayRes); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { _Res.Rows[i].Cells[j].Value = ArrayRes[i, j]; } } catch (Exception e) { MessageBox.Show(e.ToString()); } } public void MultCsh(Label _time, DataGridView _Res) { if (ArrayA == null && ArrayB == null) { MessageBox.Show("Массивы не заданы!"); } try { _Res.RowCount = N; _Res.ColumnCount = N; Stopwatch timer = new Stopwatch(); ArA = ConvertTo1(ArrayA, ArA); ArB = ConvertTo1(ArrayB, ArB); timer.Start(); for (int i = 0; i < N * N; i++) { ArRes[i] = ArA[i] * ArB[i]; } timer.Stop(); _time.Text = timer.Elapsed.ToString(); ArrayRes = ConvertTo2(ArRes, ArrayRes); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { _Res.Rows[i].Cells[j].Value = ArrayRes[i, j]; } } catch (Exception e) { MessageBox.Show(e.ToString()); } } public void AddCpp(DataGridView _Res, Label _time) { if (ArrayA == null && ArrayB == null) { MessageBox.Show("Массивы не заданы!"); } try { _Res.RowCount = N; _Res.ColumnCount = N; ArrayRes = new int[N, N]; Stopwatch timer = new Stopwatch(); ArA = ConvertTo1(ArrayA, ArA); ArB = ConvertTo1(ArrayB, ArB); timer.Start(); CD.ArAdd(ArA, ArB, N, ArRes); timer.Stop(); ArrayRes = ConvertTo2(ArRes, ArrayRes); _time.Text = timer.Elapsed.ToString(); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { _Res.Rows[i].Cells[j].Value = ArrayRes[i, j]; } } catch (Exception e) { MessageBox.Show(e.ToString()); } } public void MultCpp(DataGridView _Res, Label _time) { if (ArrayA == null && ArrayB == null) { MessageBox.Show("Массивы не заданы!"); } try { _Res.RowCount = N; _Res.ColumnCount = N; ArrayRes = new int[N, N]; Stopwatch timer = new Stopwatch(); ArA = ConvertTo1(ArrayA, ArA); ArB = ConvertTo1(ArrayB, ArB); timer.Start(); CD.ArMult(ArA, ArB, N, ArRes); timer.Stop(); ArrayRes = ConvertTo2(ArRes, ArrayRes); _time.Text = timer.Elapsed.ToString(); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { _Res.Rows[i].Cells[j].Value = ArrayRes[i, j]; } } catch (Exception e) { MessageBox.Show(e.ToString()); } } public void AddXmm(DataGridView _Res, Label _time) { if (ArrayA == null && ArrayB == null) { MessageBox.Show("Массивы не заданы!"); } try { _Res.RowCount = N; _Res.ColumnCount = N; ArrayRes = new int[N, N]; Stopwatch timer = new Stopwatch(); ArA = ConvertTo1(ArrayA, ArA); ArB = ConvertTo1(ArrayB, ArB); timer.Start(); CD.ArAddXmm(ArA, ArB, N, ArRes); timer.Stop(); ArrayRes = ConvertTo2(ArRes, ArrayRes); _time.Text = timer.Elapsed.ToString(); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { _Res.Rows[i].Cells[j].Value = ArrayRes[i, j]; } } catch (Exception e) { MessageBox.Show(e.ToString()); } } public int[] ConvertTo1(int[,] ar, int[] ar1) { int z = 0; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { ar1[z] = ar[i, j]; z++; } return ar1; } public int[,] ConvertTo2(int[] ar, int[,] ar1) { int z = 0; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { ar1[i, j] = ar[z]; z++; } return ar1; } } } using System.Runtime.InteropServices; namespace Работа_с_библиотеками { class CshDll { public void ArMult(int[] arr, int[] arr1, int l, int[] arr2) { Mult(arr, arr1, l, arr2); } public void ArAdd(int[] arr, int[] arr1, int l, int[] arr2) { Add(arr, arr1, l, arr2); } public void ArAddXmm(int[] arr, int[] arr1, int l, int[] arr2) { AddXmm(arr, arr1, l, arr2); } [DllImport("Library.dll", EntryPoint = "Add", CharSet = CharSet.Auto, SetLastError = false)] public static extern void Add(int[] array, int[] arr1, int length, int[] arr2); [DllImport("Library.dll", EntryPoint = "Mult", CharSet = CharSet.Auto, SetLastError = false)] public static extern void Mult(int[] array, int[] arr1, int length, int[] arr2); [DllImport("Library.dll", EntryPoint = "AddXmm", CharSet = CharSet.Auto, SetLastError = false)] public static extern void AddXmm(int[] array, int[] arr1, int length, int[] arr2); } } #include #ifdef __cplusplus extern "C" { #endif __declspec(dllexport) void Mult(int32_t *Array, int32_t *Array1, int length, int32_t *Array2) { for (int i = 0; i { Array2[i] = Array[i] * Array1[i]; } return; } __declspec(dllexport) void Add(int32_t *Array, int32_t *Array1, int length, int32_t *Array2) { for (int i = 0; i { Array2[i] = Array[i] + Array1[i]; } return; } __declspec(dllexport) void __stdcall AddXmm(int *Array, int *Array1, int length, int *Array2) { int *pA; int *pB; int *pRes; int s; pA = Array1; pB = Array; pRes = Array2; _asm { push ECX mov ESI, 0 pxor xmm0, xmm0 mov ECX, 32 Circ: movups xmm1, Array[ESI] addps xmm0, xmm1 movups Array2[ESI], xmm0 add ESI, 16 sub ECX, 16 jnz Circ pop ECX } return; } #ifdef __cplusplus } #endif using System; namespace Работа_с_библиотеками { public partial class frmDLL : MetroFramework.Forms.MetroForm { CshCom CSC = new CshCom(); public int lengh; public frmDLL() { InitializeComponent(); dgvACP.ColumnHeadersVisible = false; dgvACS.ColumnHeadersVisible = false; dgvAXMM.ColumnHeadersVisible = false; dgvBCP.ColumnHeadersVisible = false; dgvBCS.ColumnHeadersVisible = false; dgvBXMM.ColumnHeadersVisible = false; dgvResCP.ColumnHeadersVisible = false; dgvResCS.ColumnHeadersVisible = false; dgvResXMM.ColumnHeadersVisible = false; dgvACP.RowHeadersVisible = false; dgvACS.RowHeadersVisible = false; dgvAXMM.RowHeadersVisible = false; dgvBCP.RowHeadersVisible = false; dgvBCS.RowHeadersVisible = false; dgvBXMM.RowHeadersVisible = false; dgvResCP.RowHeadersVisible = false; dgvResCS.RowHeadersVisible = false; dgvResXMM.RowHeadersVisible = false; } private void btnGen_Click(object sender, EventArgs e) { lengh = Int32.Parse(tbN.Text); CSC.Gen(lengh); CSC.Show(dgvACS, dgvBCS, lengh); CSC.Show(dgvACP, dgvBCP, lengh); CSC.Show(dgvAXMM, dgvBXMM, lengh); for (int i = 0; i < lengh; i++) { dgvACS.Columns[i].Width = 40; dgvBCS.Columns[i].Width = 40; dgvACP.Columns[i].Width = 40; dgvBCP.Columns[i].Width = 40; dgvAXMM.Columns[i].Width = 40; dgvBXMM.Columns[i].Width = 40; } } private void btnAddCsh_Click(object sender, EventArgs e) { CSC.AddCs(lblCsh, dgvResCS); for (int i = 0; i < lengh; i++) { dgvResCS.Columns[i].Width = 40; } } private void btnMultCsh_Click(object sender, EventArgs e) { CSC.MultCsh(lblCsh, dgvResCS); for (int i = 0; i < lengh; i++) { dgvResCS.Columns[i].Width = 40; } } private void btnAddCpp_Click(object sender, EventArgs e) { CSC.AddCpp(dgvResCP, lblCpp); } private void btnMultCpp_Click(object sender, EventArgs e) { CSC.MultCpp(dgvResCP, lblCpp); } private void btnAddXmm_Click(object sender, EventArgs e) { CSC.AddXmm(dgvResXMM, lblXmm); } } } 5. Протокол отладки. Заметим, что при первом сложении с использованием динамической библиотеки, время сложения без использования dll значительно меньше, поскольку происходит затрата времени на подключение динамической библиотеки к проекту. При последующем сложении, меньше всего времени занимает сложение массивов посредством динамической библиотеки с использованием XMM регистров. |