Показать сообщение отдельно
  #1  
Старый 24.06.2016, 19:37
drcham drcham вне форума
Прохожий
 
Регистрация: 24.06.2016
Сообщения: 2
Версия Delphi: Delphi Seattle
Репутация: 10
По умолчанию потоки ttask получение и передача параметров

Добрый день всем. Требуется распараллелить вычисление интеграла. Алгоритм сам выглядит так:
Необходимо посчитать интеграл в диапазоне [a,b] f(t)=sin(x*t)dx (на деле формула в три раза длиннее).

Поскольку интервал очень большой и из-за специфики функции его расчет возможен только по расчету суммы на каждом периоде sin. Т.е. в программе сделан цикл по каждому периоду синуса и общая сумма потом складывается. Считает все это программа довольно медленно. Поэтому решено сделать расчет с использованием потоков.

Прочитал что есть класс TTask.
Сделал:
Код:
Для теста можно функцию integrator в любом виде представить.

var
     tasks: array of ITask;
     sums:array of double;
     i:integer;
     int_period_start,int_period_end:extended;
     total:extended;
begin
   Setlength (tasks ,norm_period_count); //число периодов синуса в [a,b]
   Setlength (sums ,norm_period_count);// массив куда суммы на каждом периоде записывать
   for i := 0 to trunc(norm_period_count)-1 do //цикл по периодам
   begin
     int_period_start:=i*period; //a 
     int_period_end:=(i+1)*period; //b
     // диапазон на котором интегрировать на каждом потоке
      Tasks[i] := TTask.Create (procedure()
        begin
          //в поток выносим вычисление.
          res:=Integrator(i*period, (i+1)*period,current_time);
          //current_time - это "t" или точка времени в которой надо посчитать интеграл. 
          //TInterlocked.Exchange(sums[i],res);
          //Result:=res;
//              TThread.Synchronize(nil,
//            procedure
//            begin
//                  sums[1]:=res;
//            end);
       end);
      Tasks[i].Start; //запускаем поток

    end;

  TTask.WaitForAll(tasks); //ждем завершения
  total:=0;
 for i := 0 to High(sums) do
  begin
    total:=total+sums[i];// считает сумму и выдаем результат.
  end;
   Result:=total;

К сожалению моих знаний катастрофически не хватает.
В текущем варианте функция даже работает но в массив sums ничего не записывает. Пробовал оба варианта. Они закомментированы сейчас.

Прошу помощи как отладить данный алгоритм. Может быть надо iFuture использовать... хотя я тоже пробовал, но не смог реализовать.

Повторюсь что задача состоит в том, чтобы запустить параллельно в отдельном потоке вычисление интегрирования на заданном участке. В ответ получить значение суммы и потом просто сложить их. Количество периодов будет расти и довольно сильно т.к. sin (2*pi/t), а t это время которое считает от 1мкс до 800мкс в среднем.

Заранее спасибо. Могу поблагодарить если потребуется.
Ответить с цитированием