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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 15.01.2013, 00:42   #11
Григоренко Степан
Пользователь
 
Регистрация: 05.05.2011
Сообщений: 35
По умолчанию

Цитата:
во вторых быстрее "скомпилировать" формулу в некоторый плоский байткод, а не бегать по кейзу каждый раз разбирая формулу
что это за "плоский байткод"?

Цитата:
Байт-код — машинно-независимый код низкого уровня, генерируемый транслятором и исполняемый интерпретатором.
то есть, надо либо писать свой компилятор, либо учить ассемблер, либо вводить потоки, либо курить OpenCL.

Okay, пошел mov it mov it ((
Григоренко Степан вне форума Ответить с цитированием
Старый 15.01.2013, 03:14   #12
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,774
По умолчанию

При беглом просмотре кода так и не понял, зачем понадобилось хранить промежуточные результаты вычислений в виде строк.
Vapaamies вне форума Ответить с цитированием
Старый 15.01.2013, 04:20   #13
SNUPY
Форумчанин
 
Регистрация: 15.02.2008
Сообщений: 621
По умолчанию

Цитата:
Сообщение от Григоренко Степан Посмотреть сообщение
что это за "плоский байткод"?



то есть, надо либо писать свой компилятор, либо учить ассемблер, либо вводить потоки, либо курить OpenCL.

Okay, пошел mov it mov it ((
Для простенького итератора достаточно знать базис. А так еще раз повторюсь сперва на перво необходимо избавиться от ресурсоемких операций.
Помог? Ну так нажми на весы!
SNUPY вне форума Ответить с цитированием
Старый 15.01.2013, 05:37   #14
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

в плоский байт код - имеется ввиду
структура с линейным исполнением (0..n) с минимальным ветвлением (т.е. без тучного кейза) и заранее выстроенной последовательностью вычислений, в которой максимально развернуты все предварительные вычисления (приведение типов констант StrToFloat), а по возможности свернуты математические операции с ними (например x*2/10 превращается в x/5)

можно предвычислять формулу т.к. 2 из координат меняются гораздо реже
например f=x+y+z превратится в цикле по y в f=2+y

можно поискать другие вычисляторы
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 15.01.2013 в 05:45.
Slym вне форума Ответить с цитированием
Старый 15.01.2013, 07:31   #15
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
При беглом просмотре кода так и не понял, зачем понадобилось хранить промежуточные результаты вычислений в виде строк.
Убрал FloatToStr стало быстрее меньше чем на 10%

перепроверил почти двукратный прирост скорости

дайте формулу, а то тестируюсь на +x+yz
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 15.01.2013 в 09:02.
Slym вне форума Ответить с цитированием
Старый 15.01.2013, 07:59   #16
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,774
По умолчанию

Я бы еще посоветовал перейти от динамического массива к чему-то TList и задать ему Capacity равной или даже превышающей глубину вложений при вычислениях, чтобы исключить перераспределение памяти, которое тоже очень медленно.
Vapaamies вне форума Ответить с цитированием
Старый 15.01.2013, 09:01   #17
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
Я бы еще посоветовал перейти от динамического массива к чему-то TList и задать ему Capacity равной или даже превышающей глубину вложений при вычислениях, чтобы исключить перераспределение памяти, которое тоже очень медленно.
не надо, Capacity в коде уже заложен и равен 5

кстати добился 3х кратного прироста скорости
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 15.01.2013 в 09:41.
Slym вне форума Ответить с цитированием
Старый 17.01.2013, 16:08   #18
Григоренко Степан
Пользователь
 
Регистрация: 05.05.2011
Сообщений: 35
По умолчанию

Идея для оптимизации: процедурный тип.


Код:
type
  FuncType=function(a2,a1: Real):Real;

  TStack=Record
    Data: array of FuncType;
    MaxD: Integer;
    Num: array of Real;
    MaxN: Integer;
  end;

var
  Form1: TForm1;
  Osn: TStack;
  a2, a1: Real;

function Calculate(FT: FuncType; a2,a1: Real): Real;
begin
  Result:= FT(a2,a1);
end;

function p(a2,a1: Real):Real;
begin
  Result:= a2+a1;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  a2:= 7;
  a1:= 2;

  SetLength(Osn.Data,1); 
  Osn.Data[0]:= p;
  Osn.MaxD:= 0;

  a2:= Calculate(Osn.Data[Osn.MaxD][1],a2,a1);
  Label1.Caption:= floattostr(a2);
end;
Результат выдает вполне верный. Но придется серьезно переделывать и перевод в стек, и расчет значения: Стек разбит на 2 подстека: в одном операторы, в другом числа. И какой-нибудь оператор будет означать, что надо вынуть верхнее число из числового подстека (чтобы избавиться от перевода в строку и обратно).

Последний раз редактировалось Григоренко Степан; 17.01.2013 в 16:14.
Григоренко Степан вне форума Ответить с цитированием
Старый 17.01.2013, 21:16   #19
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,774
По умолчанию

Я сейчас скажу глупость, но вызов процедуры по косвенному (сохраненному) адресу медленней, чем простой вызов с case. Вариант с case хорошо укладывается в кэш процессора и дает работу предсказателю переходов, а косвенный вызов наоборот, сбрасывает конвейер.
Vapaamies вне форума Ответить с цитированием
Старый 18.01.2013, 05:35   #20
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
Я сейчас скажу глупость, но вызов процедуры по косвенному (сохраненному) адресу медленней, чем простой вызов с case. Вариант с case хорошо укладывается в кэш процессора и дает работу предсказателю переходов, а косвенный вызов наоборот, сбрасывает конвейер.
согласен для простых операндов +-*/ sin cos компилятор делает инлайн и это быстро выполняется, но другие операнды указанные (ксякие аркосины) в проге всеравно калются...

и вот тут нужна целевая формула которую автар упорно не хочет показывать

мой вариант не супер кардинально оптимизированный
быстрее почти в 4 раза приложение тест внизу
Код:
unit Unit2;

interface
uses SysUtils,Math;
type
  TStackStr = record
    Max: Integer;
    Data: array of String;
  End;

  TStackExtended = record
    Max: Integer;
    Data: array of Extended;
  End;

Procedure Push(var Stack: TStackStr;const ch: string);
Procedure Pop(var Stack: TStackStr; Var ch: string);
function StackStr(const Str:array of string):TStackStr;


Procedure PushExtended(var Stack: TStackExtended;const Value: Extended);
Procedure PopExtended(var Stack: TStackExtended;out Value: Extended);

function Calc(const Func:TStackStr;x,y,z:extended):extended;

implementation

const
  GrowSize=32;

Procedure Push(var Stack: TStackStr;const ch: string);
begin
  if Stack.Max = Length(Stack.Data) then
    SetLength(Stack.Data, Stack.Max + GrowSize);
  Stack.Data[Stack.Max] := ch;
  Stack.Max := Stack.Max + 1;
end;

Procedure Pop(var Stack: TStackStr; Var ch: string);
begin
  if Length(Stack.Data) > 0 then
  begin
    Stack.Max := Stack.Max - 1;
    ch := Stack.Data[Stack.Max];
    if Length(Stack.Data) - Stack.Max > GrowSize then
      SetLength(Stack.Data, Stack.Max);
  end;
end;

function StackStr(const Str:array of string):TStackStr;
var i:integer;
begin
  result.Max:=Length(Str);
  SetLength(result.Data,Length(Str));
  for i:=low(Str) to High(Str) do
    result.Data[i]:=Str[i];
end;

Procedure PushExtended(var Stack: TStackExtended;const Value: Extended);
begin
  with Stack do
  begin
    if Max = Length(Data) then
      SetLength(Data, Max + GrowSize);
    Data[Max]:=Value;
    Inc(Max);
  end;
end;

Procedure PopExtended(var Stack: TStackExtended;out Value: Extended);
begin
  with Stack do
  begin
    if Max>0 then
    begin
      Dec(Max);
      Value := Data[Max];
      if Length(Data)-Max > GrowSize then
        SetLength(Data, Max);
    end;
  end;
end;

function Calc(const Func:TStackStr;x,y,z:extended):extended;
var
  Data:TStackExtended;
  Value,a1,a2:extended;
  i:integer;
  Str:string;
begin
  Data.Max := 0;
  i:=Func.Max;
  while (i>0) do
  begin
    Dec(i);
    Str:=Func.Data[i];
    case Str[1] of
      'x': Value:= X;
      'y': Value:= Y;
      'z': Value:= Z;
      //è êîíñòàíòû
      'p': Value:= Pi;
      '0'..'9': Value:= StrToFloat(Str);
      else //îïåðàòîðû
      begin
        PopExtended(Data, a2);
        if str[1] in ['+', '-', '*', '/', '^'] then
          PopExtended(Data, a1);
        case str[1] of
          '+': Value:= a1 + a2;
          '-': Value:= a1 - a2;
          '/': Value:= a1 / a2;
          '*': Value:= a1 * a2;
          '^':begin
                if a2 <= 0 then
                  Value:= 1/Power(a1, abs(a2))
                else
                  Value:= Power(a1, a2);
              end;
          '!':begin
                if a2 = 0 then
                  Value:= 1
                else
                  Value:= sqrt(2*Pi*a2)*Power((a2/2.71828),a2);
              end;
          'c': Value:=cos(a2);
          's': Value:=sin(a2);
          't': Value:=tan(a2);
          'g': Value:=cot(a2);
          'l': Value:=ln(a2);
          'e': Value:=exp(a2);
          'a': Value:=arcsin(a2);
          'b': Value:=arccos(a2);
          'w': Value:=arctan(a2);
          'd': Value:=arccot(a2);
          'o': Value:=sinh(a2);
          'k': Value:=cosh(a2);
          'm': Value:=tanh(a2);
          'n': Value:=coth(a2);
          'i': Value:=sign(a2);
          'u': Value:=abs(a2);
          'r': begin Randomize;Value:=Random(Trunc(a2));end;
          else Value:=0;
        end; //case
      end;// else
    end;//case
    PushExtended(Data, Value);
  end; //while
  PopExtended(Data,result);
end;


procedure Test;
var
  Func:TStackStr;
  i,j,k:integer;
begin
  {Func:=StackStr(['^','y','z']);
  for I := 0 to CubeNumberZ - 1 do
    for J := 0 to CubeNumberX - 1 do
      for K := 0 to CubeNumberY - 1 do
      with Cube[I, J, K] do
      try
        Result:=Calc(Func,Coord.X,Coord.Y,Coord.Z);
      except
        on EOverflow do
        begin
          Result:=MaxExtended;
          IfBound:= false;
        end;
      end;}
end;
end.
Вложения
Тип файла: zip Calc.zip (5.4 Кб, 5 просмотров)
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 18.01.2013 в 06:18.
Slym вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Автозапуск приложения. Но вопрос совсем не про автозапуск приложения. avd Общие вопросы Delphi 4 30.08.2012 22:24
После запуска приложения из службы созданной на C# не отображается иконка приложения dmail1976 Общие вопросы .NET 1 22.09.2011 13:38
Делаю сайты, пишу маленькие/большие скрипты. Пишу веб-приложения и приложения под Windows. SkyM@n Фриланс 3 29.12.2007 16:21