51312

Использование SIMD-расширений

Лабораторная работа

Информатика, кибернетика и программирование

Цель работы Научиться использовать в программах SIMD-расширения архитектуры х86. Написать программу с использованием SIMD-расширений.

Русский

2014-02-09

103 KB

1 чел.

Министерство образования и науки

ФГБОУ ВПО Тульский государственный университет

КАФЕДРА АВТОМАТИКИ И ТЕЛЕМЕХАНИКИ

Использование SIMD-расширений

Отчет по лабораторной работе № 6

по дисциплине «Кодирование и сжатие данных»

Выполнил:                студент группы      230691   __________  Гриценко И.В.

                                      (подпись)                                            

Проверил:                                                                 __________  Гетманец В.М.

                                                              (подпись)

Тула 2013
Цель работы

 Научиться использовать в программах SIMD-расширения архитектуры х86. Написать программу с использованием SIMD-расширений.

Задание на работу

Реализовать приложение для выполнения простейших арифметических действий с матрицами с использованием SIMD-расширений.

Ход работы

В ходе выполнения данной работы была разработана программа реализующая сложение, вычитание и умножение матриц с использованием SIMD-расширений. Ниже представлен текст этой программы, написанной на языке Delphi.

unit MUnit;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, StdCtrls, ExtCtrls, cxGraphics, cxControls, cxLookAndFeels,

 cxLookAndFeelPainters, cxContainer, cxEdit, Grids, cxTextEdit,

 cxMaskEdit, cxSpinEdit, dxLayoutContainer, dxLayoutcxEditAdapters,

 dxLayoutControlAdapters, Menus, cxButtons, dxLayoutControl, dxBevel,

 cxLabel;

type

 TfrmMain = class(TForm)

   dxLayoutControl1Group_Root: TdxLayoutGroup;

   dxLayoutControl1: TdxLayoutControl;

   sgA: TStringGrid;

   dxLayoutControl1Item1: TdxLayoutItem;

   seN: TcxSpinEdit;

   dxLayoutControl1Item2: TdxLayoutItem;

   dxLayoutControl1Group1: TdxLayoutGroup;

   sgB: TStringGrid;

   dxLayoutControl1Item6: TdxLayoutItem;

   teTReg: TcxTextEdit;

   dxLayoutControl1Item7: TdxLayoutItem;

   teTMMX: TcxTextEdit;

   dxLayoutControl1Item8: TdxLayoutItem;

   seNum: TcxSpinEdit;

   dxLayoutControl1Item9: TdxLayoutItem;

   dxLayoutControl1Group4: TdxLayoutGroup;

   sgC: TStringGrid;

   dxLayoutControl1Item10: TdxLayoutItem;

   btnAdd: TcxButton;

   dxLayoutControl1Item11: TdxLayoutItem;

   btnSub: TcxButton;

   dxLayoutControl1Item12: TdxLayoutItem;

   btnMul: TcxButton;

   dxLayoutControl1Item13: TdxLayoutItem;

   lbEq: TcxLabel;

   dxLayoutControl1Item14: TdxLayoutItem;

   dxLayoutControl1Group2: TdxLayoutGroup;

   dxLayoutControl1Group6: TdxLayoutGroup;

   dxLayoutControl1Item15: TdxLayoutItem;

   bvSeparator1: TdxBevel;

   dxLayoutControl1Item16: TdxLayoutItem;

   bvSeparator2: TdxBevel;

   procedure seNPropertiesChange(Sender: TObject);

   procedure sgAKeyPress(Sender: TObject; var Key: Char);

   procedure FormCreate(Sender: TObject);

   procedure seNumPropertiesChange(Sender: TObject);

   procedure btnMulClick(Sender: TObject);

   procedure btnAddClick(Sender: TObject);

   procedure btnSubClick(Sender: TObject);

 private

   { Private declarations }

 public

   { Public declarations }

 end;

 TArray4 = array [0..3] of Smallint;

 TArray2 = array [0..1] of Longint;

 TMatrInt = array of array of Smallint;

 TMatrReal = array of array of Real;

var

 frmMain: TfrmMain;

implementation

uses Math;

{$R *.dfm}

function MAddMMX(m1: TMatrInt; nm1, mm1: Integer; m2: TMatrInt; nm2, mm2: Integer;

 var mr: TMatrInt): Extended;

var       

 QPF, T1, T2: Int64;

 i, k: Integer;

 ar1, ar2: TArray4;

 ares: TArray4;

begin

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(T1);

 for i := 0 to nm1-1 do

 begin

   k := 1;

   while k < mm1 do

   begin

     ar1[0] := m1[i,k-1]; ar1[1] := m1[i,k]; ar1[2] := m1[i,k+1]; ar1[3] := m1[i,k+2];

     ar2[0] := m2[i,k-1]; ar2[1] := m2[i,k]; ar2[2] := m2[i,k+1]; ar2[3] := m2[i,k+2];

     asm

       movq MM0, ar1[0]

       movq MM1, ar2[0]

       paddw MM0, MM1

       movq ares[0], MM0

       emms

     end;

     mr[i,k-1] := ares[0]; mr[i,k] := ares[1]; mr[i,k+1] := ares[2]; mr[i,k+2] := ares[3];

     Inc(k, 4);

   end;

 end;

 QueryPerformanceCounter(T2);

 Result := (T2 - T1) / QPF;

end;

function MSubMMX(m1: TMatrInt; nm1, mm1: Integer; m2: TMatrInt; nm2, mm2: Integer;

 var mr: TMatrInt): Extended;

var       

 QPF, T1, T2: Int64;

 i, k: Integer;

 ar1, ar2: TArray4;

 ares: TArray4;

begin

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(T1);

 for i := 0 to nm1-1 do

 begin

   k := 1;

   while k < mm1 do

   begin

     ar1[0] := m1[i,k-1]; ar1[1] := m1[i,k]; ar1[2] := m1[i,k+1]; ar1[3] := m1[i,k+2];

     ar2[0] := m2[i,k-1]; ar2[1] := m2[i,k]; ar2[2] := m2[i,k+1]; ar2[3] := m2[i,k+2];

     asm

       movq MM0, ar1[0]

       movq MM1, ar2[0]

       psubw MM0, MM1

       movq ares[0], MM0

       emms

     end;

     mr[i,k-1] := ares[0]; mr[i,k] := ares[1]; mr[i,k+1] := ares[2]; mr[i,k+2] := ares[3];

     Inc(k, 4);

   end;

 end;

 QueryPerformanceCounter(T2);

 Result := (T2 - T1) / QPF;

end;

function MMulMMX(m1: TMatrInt; nm1, mm1: Integer; m2: TMatrInt; nm2, mm2: Integer;

 var mr: TMatrInt): Extended;

var       

 QPF, T1, T2: Int64;

 i, j, k: Integer;

 ar1, ar2: TArray4;

 ares: TArray2;

begin

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(T1);

 for i := 0 to nm1-1 do

   for j := 0 to mm2-1 do

   begin

     k := 1;

     while k < mm1 do

     begin

       ar1[0] := m1[i,k-1]; ar1[1] := m1[i,k]; ar1[2] := m1[i,k+1]; ar1[3] := m1[i,k+2];

       ar2[0] := m2[k-1,j]; ar2[1] := m2[k,j]; ar2[2] := m2[k+1,j]; ar2[3] := m2[k+2,j];

       asm

         movq MM0, ar1[0]

         movq MM1, ar2[0]

         pmaddwd MM0, MM1

         movq ares[0], MM0

         emms

       end;

       mr[i,j] := ares[0] + ares[1];

       Inc(k, 4);

     end;

   end;   

 QueryPerformanceCounter(T2);

 Result := (T2 - T1) / QPF;

end;

function MAddRegular(m1: TMatrInt; nm1, mm1: Integer; m2: TMatrInt; nm2, mm2: Integer;

 var mr: TMatrInt): Extended;

var

 QPF, T1, T2: Int64;

 i, j: Integer;

begin

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(T1);

 for i := 0 to nm1-1 do

   for j := 0 to mm2-1 do

   begin

     mr[i,j] := 0;

     mr[i,j] := mr[i,j] + m1[i,j] + m2[i,j];

   end;

 QueryPerformanceCounter(T2);

 Result := (T2 - T1) / QPF;

end;

function MSubRegular(m1: TMatrInt; nm1, mm1: Integer; m2: TMatrInt; nm2, mm2: Integer;

 var mr: TMatrInt): Extended;

var

 QPF, T1, T2: Int64;

 i, j: Integer;

begin

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(T1);

 for i := 0 to nm1-1 do

   for j := 0 to mm2-1 do

   begin

     mr[i,j] := 0;

     mr[i,j] := mr[i,j] + m1[i,j] - m2[i,j];

   end;

 QueryPerformanceCounter(T2);

 Result := (T2 - T1) / QPF;

end;

function MMulRegular(m1: TMatrInt; nm1, mm1: Integer; m2: TMatrInt; nm2, mm2: Integer;

 var mr: TMatrInt): Extended;

var

 QPF, T1, T2: Int64;

 i, j, k: Integer;

begin

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(T1);

 for i := 0 to nm1-1 do

   for j := 0 to mm2-1 do

   begin

     mr[i,j] := 0;

     for k := 0 to mm1-1 do

       mr[i,j] := mr[i,j] + m1[i,k]*m2[k,j];

   end;  

 QueryPerformanceCounter(T2);

 Result := (T2 - T1) / QPF;

end;

procedure TfrmMain.seNPropertiesChange(Sender: TObject);

var

 i, j, n: Integer;

begin

 n := seN.Value;

 sgA.ColCount := n;

 sgA.RowCount := n;

 sgB.ColCount := n;

 sgB.RowCount := n;

 sgC.ColCount := n;

 sgC.RowCount := n;

 for i := 0 to n-1 do

   for j := 0 to n-1 do

   begin

     if sgA.Cells[i,j] = '' then

       sgA.Cells[i,j] := '0';

     if sgB.Cells[i,j] = '' then

       sgB.Cells[i,j] := '0';

   end;

 for i := 0 to n-1 do

   sgC.Cols[i].Clear;

 teTReg.Clear;

 teTMMX.Clear;

end;

procedure TfrmMain.sgAKeyPress(Sender: TObject; var Key: Char);

begin

 teTReg.Clear;

 teTMMX.Clear;

end;

procedure TfrmMain.seNumPropertiesChange(Sender: TObject);

begin

 teTReg.Clear;

 teTMMX.Clear;

end;

procedure TfrmMain.FormCreate(Sender: TObject);

begin

 seN.Value := 4;

end;

procedure TfrmMain.btnAddClick(Sender: TObject);

var

 n, num, i, j: Integer;

 a, b, c: TMatrInt;

 time_reg, time_mmx: extended;

 QPF, t1, t2: Int64;

begin

 n := seN.Value;

 num := seNum.Value;

 SetLength(a, n, n);

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     a[i,j] := strtoint(sgA.Cells[j,i]);

 SetLength(b, n, n);

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     b[i,j] := strtoint(sgB.Cells[j,i]);

 SetLength(c, n, n);

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(t1);

 for i := 1 to num do

   MAddRegular(a, n, n, b, n, n, c);

 QueryPerformanceCounter(t2);

 time_reg := (t2 - t1) / QPF;

 QueryPerformanceCounter(t1);

 for i := 1 to num do

   MAddMMX(a, n, n, b, n, n, c);

 QueryPerformanceCounter(t2);

 time_mmx := (t2 - t1) / QPF;

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     sgC.Cells[j,i] := inttostr(c[i,j]);

 teTReg.Text := floattostr(time_reg);

 teTMMX.Text := floattostr(time_mmx);

end;

procedure TfrmMain.btnSubClick(Sender: TObject);

var

 n, num, i, j: Integer;

 a, b, c: TMatrInt;

 time_reg, time_mmx: extended;

 QPF, t1, t2: Int64;

begin

 n := seN.Value;

 num := seNum.Value;

 SetLength(a, n, n);

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     a[i,j] := strtoint(sgA.Cells[j,i]);

 SetLength(b, n, n);

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     b[i,j] := strtoint(sgB.Cells[j,i]);

 SetLength(c, n, n);

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(t1);

 for i := 1 to num do

   MSubRegular(a, n, n, b, n, n, c);

 QueryPerformanceCounter(t2);

 time_reg := (t2 - t1) / QPF;

 QueryPerformanceCounter(t1);

 for i := 1 to num do

   MSubMMX(a, n, n, b, n, n, c);

 QueryPerformanceCounter(t2);

 time_mmx := (t2 - t1) / QPF;

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     sgC.Cells[j,i] := inttostr(c[i,j]);

 teTReg.Text := floattostr(time_reg);

 teTMMX.Text := floattostr(time_mmx);

end;

procedure TfrmMain.btnMulClick(Sender: TObject);

var

 n, num, i, j: Integer;

 a, b, c: TMatrInt;

 time_reg, time_mmx: extended;

 QPF, t1, t2: Int64;

begin

 n := seN.Value;

 num := seNum.Value;

 SetLength(a, n, n);

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     a[i,j] := strtoint(sgA.Cells[j,i]);

 SetLength(b, n, n);

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     b[i,j] := strtoint(sgB.Cells[j,i]);

 SetLength(c, n, n);

 QueryPerformanceFrequency(QPF);

 QueryPerformanceCounter(t1);

 for i := 1 to num do

   MMulRegular(a, n, n, b, n, n, c);

 QueryPerformanceCounter(t2);

 time_reg := (t2 - t1) / QPF;

 QueryPerformanceCounter(t1);

 for i := 1 to num do

   MMulMMX(a, n, n, b, n, n, c);

 QueryPerformanceCounter(t2);

 time_mmx := (t2 - t1) / QPF;

 for i := 0 to n-1 do

   for j := 0 to n-1 do

     sgC.Cells[j,i] := inttostr(c[i,j]);

 teTReg.Text := floattostr(time_reg);

 teTMMX.Text := floattostr(time_mmx);

end;

end. 

           

Тестовый пример

На рисунке 1 представлен снимок экрана, демонстрирующей работу разработанной программы при сложении матриц.

Рисунок 1 – Пример работы программы (сложение матриц)

На рисунке 2 представлен снимок экрана, демонстрирующей работу разработанной программы при вычитании матриц.

Рисунок 2 – Пример работы программы (вычитание матриц)

На рисунке 3 представлен снимок экрана, демонстрирующей работу разработанной программы при умножении матриц.

Рисунок 3 – Пример работы программы (умножение матриц)

Проанализировав рисунки 1-3 можно убедиться, что выполнение операций с использованием SIMD-расширений производится быстрее, чем с использованием стандартных операций.

Вывод

Для повышения быстродействия и качества работы программ  часто используются SIMD-расширения. Команды SIMD-расширений обеспечивают параллельную обработку нескольких байтов, слов или двойных слов. Однако следует отметить, что не во всех программах можно существенно увеличить эффективность за счет использования SIMD-расширений.


 

А также другие работы, которые могут Вас заинтересовать

67550. Выбор типа и параметров двигателя, передаточного и усилительно-преобразовательного устройств. Выбор типа электродвигателя 56 KB
  В простейших случаях тип двигателя совпадает с видом напряжения сети. При использовании усилительно-преобразовательного устройства в случае сети постоянного тока применяется мостовая схема четыре силовых электронных ключа и широтно-импульсная модуляция для питания двигателя постоянного тока или инвертор...
67551. СОСТОЯНИЯ МИКРОСИСТЕМ. ПОСТУЛАТЫ КВАНТОВОЙ МЕХАНИКИ 136 KB
  Всякая физическая теория изучает определенный класс физических систем. Одно из основных понятий любой физической теории понятие состояния физической системы которое задается переменными состояния. а Если заданы переменные состояния в некоторый фиксированный момент времени то мы имеем максимально...
67552. СОСТОЯНИЯ МИКРОСИСТЕМ. ПОСТУЛАТЫ КВАНТОВОЙ МЕХАНИКИ (ПРОДОЛЖЕНИЕ) 593.5 KB
  Разные собственные векторы при фиксированном Al автоматически не являются взаимно ортогональными. Но их всегда можно ортогонализовать процедурой Шмидта, а кроме того, их можно и нормировать.
67553. ВОЛНОВАЯ ФУНКЦИЯ ЧАСТИЦЫ. УРАВНЕНИЕ ШРЕДИНГЕРА 317.5 KB
  Здесь множитель i выделен для удобства (чтобы было = - см. ниже), а - некоторый дифференциальный оператор, не включающий производных по времени. Он должен быть линейным, чтобы соблюсти принцип суперпозиции.
67554. А-ПРЕДСТАВЛЕНИЕ КВАНТОВОЙ МЕХАНИКИ 642 KB
  Здесь предполагается, что спектр оператора - невырожденный. Если есть вырождение, то нужен еще один индекс, связанный с необходимостью введения по крайней мере еще одного оператора, коммутирующего с . Тогда строим базис из общих собственных векторов операторов и (см. лекцию 2):
67555. СООТНОШЕНИЯ НЕОПРЕДЕЛЕННОСТЕЙ 611.5 KB
  Зависимость от времени можно ввести в квантовую механику разными способами. До сих пор мы пользовались картиной Шредингера в которой считается что всю зависимость от времени несут векторы состояния волновые функции а в операторы наблюдаемых она может входить лишь в исключительных...
67556. ЗАКОНЫ СОХРАНЕНИЯ 488.5 KB
  В картине Шредингера затруднительно сразу сказать, что такое сохраняющаяся физическая величина, так как операторы наблюдаемых обычно вообще от времени не зависят. Приходится исхитряться (см. ниже). А в картине Гейзенберга все ясно.
67557. НОРМИРОВКА В НЕПРЕРЫВНОМ СПЕКТРЕ 299 KB
  Классическому инфинитному движению отвечают состояния с обобщенными волновыми функциями которые нельзя нормировать а энергетический спектр является непрерывным. Возникает проблема нормировки волновых функций непрерывного спектра. Реально же на самом деле спектр всегда является дискретным так как...
67558. ГАРМОНИЧЕСКИЙ ОСЦИЛЛЯТОР 773 KB
  Мы получили, что волновые функции стационарных состояний осциллятора являются или четными или нечетными. Оказывается, этот результат можно было предсказать заранее, не решая задачу. Сделаем в этой связи отступление, которое представляет и значительный самостоятельный интерес.