Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.10.2014, 12:57   #1
skazochnik
 
Регистрация: 05.10.2014
Сообщений: 7
По умолчанию Оптимизация вычислений с помощью потоков.

Здравствуйте, уважаемые программисты. Я хочу ускорить вычисления в циклах с помощью потоков. Для этого взял задачу умножения матриц: A[n,m] на матрицу B[m,l] Результат С [n,l]. Для этого я в отдельном модуле пишу программку MultMatr, в которой и провожу все вычисления, а вызываю ее из основного модуля. В MultMatr я создаю n потоков ( по числу строк в матрице С ) и считаю строки матрицы С в программке MultVektrMatr. В программу MultVektrMatr данные передаются ( здесь первая проблема: почему-то при отладке, когда нажимаю на F4, то она мне при первом заходе в MultVektrMatr дает уже сразу номер 3-го потока ) , т.е. строки матрицы С вычисляются. После этого я их записываю в матрицу Form2.CForm2, а затем, когда построю всю матрицу Form2.CForm2, записываю в С2. В результате в таблице StringGridC высвечивается только третья строка, еще раз нажимаю на TForm1.Button1Click - высвечивается вторая строка. Но первая строка матрицы С как была нулевой так ее и осталась.
Т.е. как работают потоки - не понятно! Может дело в синхронизации. Я ведь работаю с матрицей Form2.CForm2. Я не хочу иметь дело с синхронизацией, т.к. думаю, что это влияет на скорость вычислений.
Поэтому для передачи параметров из функции MultVektrMatr решил попробывать copyDataStruct. Так вот в обработчик WMCopyData данные не приходят вообще.
Хочу вас спросить, что я делал не так в первом и во втором случае? И как все-таки работают потоки ( хотя теории я почитал много, практического опыта мало ).
skazochnik вне форума Ответить с цитированием
Старый 06.10.2014, 12:59   #2
skazochnik
 
Регистрация: 05.10.2014
Сообщений: 7
По умолчанию

Далее текст главного и вспомогательного модуля:


Код:
unit PotokMatr1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,GlobalPeremen, Vcl.StdCtrls, Vcl.Grids,
  Vcl.Samples.Spin, UmnMatric;

type

  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    SpinEditAN: TSpinEdit;
    SpinEditAM: TSpinEdit;
    SpinEditBM: TSpinEdit;
    SpinEditBL: TSpinEdit;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    StringGridA: TStringGrid;
    StringGridB: TStringGrid;
    StringGridC: TStringGrid;
    Label7: TLabel;
    Label8: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

  N,M,L:integer;
  A, B, C:DMatrix;


implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
var
  i,j:integer;

begin

  N:=SpinEditAN.Value;
  M:=SpinEditAM.Value;
  L:=SpinEditBL.Value;

  SetLength(A,N+1,M+1);
  SetLength(B,M+1,L+1);
  SetLength(C,N+1,L+1);


  For i:=1 to N do For j:=1 to M  do
  A[i,j]:= StrToFloat(StringGridA.Cells[j,i]);

  For i:=1 to M do For j:=1 to L  do
  B[i,j]:= StrToFloat(StringGridB.Cells[j,i]);

  Form2.MultMatr(N,M,L, A,B,C);

  With StringGridC  do
    begin
      RowCount:=N+1; ColCount:=L+1; FixedRows:=1; FixedCols:=1;
      ColWidths[0]:=20;
      For i:=1 to ColCount-1 do ColWidths[1]:=50;
      Cells[0,0]:='№';
      For i:=1 to ColCount-1 do Cells[i,0]:=IntToStr(i);
      For i:=1 to RowCount-1 do Cells[0,i]:=IntToStr(i);

      For i:=1 to ColCount-1 do For j:=1 to RowCount-1 do
      Cells[i,j]:=FloatToStr(C[j,i]);
    end;

   With StringGridA  do
  begin
    RowCount:=N+1; ColCount:=M+1; FixedRows:=1; FixedCols:=1;
    ColWidths[0]:=20;
    For i:=1 to ColCount-1 do ColWidths[1]:=50;
    Cells[0,0]:='№';
    For i:=1 to ColCount-1 do Cells[i,0]:=IntToStr(i);
    For i:=1 to RowCount-1 do Cells[0,i]:=IntToStr(i);

    For i:=1 to ColCount-1 do For j:=1 to RowCount-1 do
    Cells[i,j]:=FloatToStr(A[j,i]);

  end;


end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i,j,k: integer;
begin

  N:=3;
  M:=3;
  L:=4;

  SpinEditAN.Value:=N;
  SpinEditAM.Value:=M;
  SpinEditBM.Value:=SpinEditAM.Value;
  SpinEditBL.Value:=L;


  With StringGridA  do
  begin
   RowCount:=N+1; ColCount:=M+1; FixedRows:=1; FixedCols:=1;
   ColWidths[0]:=20;
   For i:=1 to ColCount-1 do ColWidths[1]:=50;
   Cells[0,0]:='№';
   For i:=1 to ColCount-1 do Cells[i,0]:=IntToStr(i);
   For i:=1 to RowCount-1 do Cells[0,i]:=IntToStr(i);

   For i:=1 to ColCount-1 do For j:=1 to RowCount-1 do
   Cells[i,j]:=FloatToStr(j+i);
  end;

  With StringGridB  do
  begin
   RowCount:=M+1; ColCount:=L+1; FixedRows:=1; FixedCols:=1;
   ColWidths[0]:=20;
   For i:=1 to ColCount-1 do ColWidths[1]:=50;
   Cells[0,0]:='№';
   For i:=1 to ColCount-1 do Cells[i,0]:=IntToStr(i);
   For i:=1 to RowCount-1 do Cells[0,i]:=IntToStr(i);

   For i:=1 to ColCount-1 do For j:=1 to RowCount-1 do
   Cells[i,j]:='0';

   Cells[1,1]:='1';
   Cells[2,2]:='-1';
   Cells[1,2]:='1';
  end;

   With StringGridC  do
  begin
   RowCount:=N+1; ColCount:=L+1; FixedRows:=1; FixedCols:=1;
   ColWidths[0]:=20;
   For i:=1 to ColCount-1 do ColWidths[1]:=50;
   Cells[0,0]:='№';
   For i:=1 to ColCount-1 do Cells[i,0]:=IntToStr(i);
   For i:=1 to RowCount-1 do Cells[0,i]:=IntToStr(i);

   For i:=1 to ColCount-1 do For j:=1 to RowCount-1 do
   Cells[i,j]:='0';

  end;
 end;


end.
skazochnik вне форума Ответить с цитированием
Старый 06.10.2014, 13:00   #3
skazochnik
 
Регистрация: 05.10.2014
Сообщений: 7
По умолчанию

Код:
unit UmnMatric;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, GlobalPeremen, Vcl.Grids, Vcl.StdCtrls;

type
    PMultVektrMatrRecord = ^TMultVektrMatrRecord;
    TMultVektrMatrRecord = record

    N1,M1,L1 : integer;
    NomerPotoka: integer;
    U1, V1: DVector;
    Q1 : DMatrix;
    end;


  TForm2 = class(TForm)
    Button1: TButton;
    StringGridForm2C: TStringGrid;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }

     NForm2,MForm2,LForm2:integer;
     CForm2:DMatrix;

     NPotok:  TMultVektrMatrRecord;

     procedure WMCopyData(var MessageData: TWMCopyData); message WM_COPYDATA;

  public
    { Public declarations }

     procedure MultMatr(N2,M2,L2:integer; Var A2,B2,C2:DMatrix);
    {Умножение матрицы A2[n2,m2] на матрицу B2[m2,l2] Результат С2 [n2,l2]}

  end;
      function MultVektrMatr(Parameter: PMultVektrMatrRecord):Integer;
var
  Form2: TForm2;

implementation

{$R *.dfm}

function MultVektrMatr(Parameter: PMultVektrMatrRecord):Integer;
var
    i,j,k: integer;
    SumPotok: double;

    receiverHandle  : THandle;
    res : integer;
    copyDataStruct : TCopyDataStruct;
begin

    receiverHandle := FindWindow(PChar('TForm2'),PChar('Умножение матриц'));
    if receiverHandle = 0 then
    begin
       ShowMessage('CopyData Receiver NOT found!');
       Exit;
    end;

    For i:=1 to Parameter^.L1 do
       begin
         SumPotok:=0;
         For k:=1 to Parameter^.M1 do SumPotok:=SumPotok+Parameter^.U1[k]*Parameter^.Q1[k,i];
         Parameter^.V1[i]:=SumPotok;

         copyDataStruct.dwData := 111;
         copyDataStruct.cbData := SizeOf(Parameter);
         copyDataStruct.lpData := @Parameter;

         res := SendMessage(receiverHandle, WM_COPYDATA, 0, Integer(@copyDataStruct));

       end;
 {
   Сначала я пытался сразу присвоить результат соответствующему столбцу матрицы :
    For k:=1 to Parameter^.L1 do Form2.CForm2[Parameter^.NomerPotoka,k]:=Parameter^.V1[k];

   Потом, как выше, с помощью  WM_COPYDATA и  copyDataStruct.
 }

end;

procedure TForm2.MultMatr(N2,M2,L2:integer; Var A2,B2,C2:DMatrix);
var
     Nomer, i,j,k: integer;
     nom: integer;
     sum: double;
     id1 : LongWord;

begin

     NPotok.N1:=N2;
     NPotok.M1:=M2;
     NPotok.L1:=L2;

     SetLength(NPotok.U1,M2+1);
     SetLength(NPotok.V1,L2+1);
     SetLength(NPotok.Q1,M2+1,L2+1);
     SetLength(CForm2,N2+1,L2+1);

     For i:=1 to M2 do For j:=1 to L2  do  NPotok.Q1[i,j]:=B2[i,j];

     For Nomer:=1 to N2 do  For j:=1 to 2  do
         begin
            NPotok.NomerPotoka:=Nomer;
            For k:=1 to M2 do NPotok.U1[k]:=A2[Nomer,k];
                nom := BeginThread(nil, 0,
                                   Addr(MultVektrMatr),
                                   Addr(NPotok),
                                        0, id1);
             CloseHandle(nom);
         end;

      For i:=1 to N2 do For j:=1 to L2  do C2[i,j]:=CForm2[i,j];

end;

procedure TForm2.Button1Click(Sender: TObject);
var
        i,j,k: integer;
begin

   With StringGridForm2C  do
    begin
      RowCount:=NForm2+1; ColCount:=LForm2+1; FixedRows:=1; FixedCols:=1;
      ColWidths[0]:=20;
      For i:=1 to ColCount-1 do ColWidths[1]:=50;
      Cells[0,0]:='№';
      For i:=1 to ColCount-1 do Cells[i,0]:=IntToStr(i);
      For i:=1 to RowCount-1 do Cells[0,i]:=IntToStr(i);

      For i:=1 to ColCount-1 do For j:=1 to RowCount-1 do
      Cells[i,j]:=FloatToStr(CForm2[j,i]);
    end;

end;


  procedure TForm2.WMCopyData(var MessageData: TWMCopyData);
var
        i,j,k: integer;
        MRecord:  ^TMultVektrMatrRecord;

begin
       MRecord:=MessageData.CopyDataStruct.lpData;
       i:=MRecord^.NomerPotoka;
   {    For k:=1 to MRecord^.L1 do Form2.CForm2[MRecord^.NomerPotoka,k]:=MRecord^.V1[k];  }
end;


end.
skazochnik вне форума Ответить с цитированием
Старый 06.10.2014, 15:38   #4
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Подведу предварительный итог: чтобы умножить 2 матрицы, ты сделал несколько ЕХЕ-шников? Ты точно уверен, что тебе именно так нужно?

Как звучит оригинал задания?
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 06.10.2014, 18:34   #5
skazochnik
 
Регистрация: 05.10.2014
Сообщений: 7
По умолчанию

ЕХЕ-шник один, программа одна. Из одного модуля вызывается подпрограмма, которая находится в другом модуле. Задание - перемножить две матрицы. Эта подпрограмма должна использовать потоки для ускорения вычисления.
skazochnik вне форума Ответить с цитированием
Старый 06.10.2014, 19:53   #6
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Эта подпрограмма должна использовать потоки для ускорения вычисления.
Наивный чукотский юноша. Как ты проверишь ускорение?
Про втоое приложение навело на мысль сообщение WM_COPYDATA. Зачем оно түт?
Могу попробовать написать тебе пример.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 06.10.2014, 20:36   #7
skazochnik
 
Регистрация: 05.10.2014
Сообщений: 7
По умолчанию

Умножение матриц - это тестовый пример, на котором я хочу отработать алгоритм работы с потоками. Есть у меня другие задачи, где работают подобные схемы с циклами, но они считаются по часу, два и т.д.
А обработку сообщения WM_COPYDATA я решил применить как способ передачи параметров( в моем случае - результатов вычислений ) из потока в обработчик Form2, ибо написано, что sendmessage сразу обрабатывает сообщение. А в данном обработчике я уже заношу соответствующие результаты в соответствующие строки матрицы. Но, поскольку, данные не передаются, в обработчике вылетает ошибка. Поэтому я там закоментировал последние строки.
Короче, я хочу, чтобы это так и происходило, но что там на самом деле делается - мне неизвестно.
skazochnik вне форума Ответить с цитированием
Старый 06.10.2014, 20:43   #8
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
WM_COPYDATA я решил применить как способ передачи параметров( в моем случае - результатов вычислений ) из потока в обработчик Form2
дальше не читал. убери немедля и начинай курить мануалы по мңогопоточность. их есть у меня, могу поделиться.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 06.10.2014, 20:54   #9
skazochnik
 
Регистрация: 05.10.2014
Сообщений: 7
По умолчанию

Поделись, если не трудно. Буду рад.
skazochnik вне форума Ответить с цитированием
Старый 06.10.2014, 20:59   #10
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

не жалко, качай.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Многократное использование потоков(пул потоков) ProgrammistRT Общие вопросы Delphi 10 06.04.2014 13:42
Пересчет вычислений Trimbl Microsoft Office Excel 1 23.05.2013 18:25
Параметры вычислений Trimbl Microsoft Office Excel 2 18.02.2012 15:25
Параллельные вычислений Иллидан Общие вопросы C/C++ 1 22.11.2010 13:07
Оптимизация кода с помощью нейронных сетей Levsha100 Общие вопросы по программированию, компьютерный форум 5 14.01.2010 11:51