Требуется разъяснение Специалистов

Любые обсуждения, не нарушающие правил форума.

Модератор: Модераторы

Требуется разъяснение Специалистов

Сообщение pro_berserk » 31.10.2017 15:45:11

Доброго времени суток, уважаемые форумчане, любители FreePascal и Lazarus.
Помогите пожалуйста понять причину следующего "явления", самому увы в силу уровня знаний, понять не удаётся :(
Начну из далека: Решился я таки посмотреть что за зверь такой этот PascalABC.NET (Далее PABC) открыл я значит Данный документ, читаю какой FPC убогий и прочие восхваление PABC, дохожу до страницы №8 (Это все на что меня хватило :D ) и вижу там заявление, что производительность программ на PABC выше чем на FPC, честно говоря задело.
Установил PABC перенес примеры из текста по сравнению производительности, проверяю, расстраиваюсь:
Код PABC: Среднее время выполнения на моем Intel i5-4210H - 425мс
Код: Выделить всё
begin
var n := 10000;
var s := 0.0;
for var i:=1 to n do
for var j:=1 to n do
s += 1.0/(i*j);
writeln(Milliseconds); 
end.

Код FPC: Среднее время выполнения - 575мс
Код: Выделить всё
var
  tt:Cardinal;
  n,i,j: integer;
  s: real;
begin
tt:=GetTickCount64;
n := 10000;
s := 0.0;
for i:=1 to n do
for j:=1 to n do
s += 1.0/(i*j);
writeln('Tick: ',GetTickCount64-tt);
ReadLn;
end;]                     

Крайне не довольный результатом, лезу в реализацию функции Milliseconds в PABC, "как могу переношу" её в FPC:
Код: Выделить всё
StartTime:=Time; //Переменная назначается при старте программы естественно
//Остальное после цикла
cur_t:=Time;
ml:= cur_t-StartTime;
WriteLn('Milliseconds: ',IntToStr(DateTimeToTimeStamp(ml).Time) );

Получаю среднее время выполнения - 265мс
Выношу код выше в отдельную функцию и вызываю её: Среднее время выполнения - 565мс

С чем это может быть связанно помогите разобраться пожалуйста...
pro_berserk
новенький
 
Сообщения: 21
Зарегистрирован: 05.11.2013 14:02:33

Re: Требуется разъяснение Специалистов

Сообщение SSerge » 31.10.2017 16:04:04

pro_berserk писал(а): какой FPC убогий и прочие восхваление PABC, дохожу до страницы №8


они там в "документе" если и сравнивают с fpc, то с версией примерно 0.9 :D

pro_berserk писал(а):Среднее время выполнения - 565мс


не под отладчиком ли?
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Требуется разъяснение Специалистов

Сообщение pro_berserk » 31.10.2017 16:12:35

SSerge писал(а):они там в "документе" если и сравнивают с fpc, то с версией примерно 0.9 :D

В документе указано FPC 3.0, а там как на самом деле, кто его знает... У меня стоит FPC 3.0.2
SSerge писал(а):не под отладчиком ли?

Отладкой не пользовался, вообще ни чего не делал, режим компиляции Default
pro_berserk
новенький
 
Сообщения: 21
Зарегистрирован: 05.11.2013 14:02:33

Re: Требуется разъяснение Специалистов

Сообщение SSerge » 31.10.2017 16:28:59

Кста, если хочется ада, угара и трэша, сравнивайте их на работе строковых операций, особенно касающихся извлечения отдельных символов, их перестановки и т.д. Если ABC использует строковые библиотеки .NET, у него есть все шансы выиграть в РАЗЫ.
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Требуется разъяснение Специалистов

Сообщение pro_berserk » 31.10.2017 16:53:28

SSerge писал(а):Кста, если хочется ада, угара и трэша, сравнивайте их на работе строковых операций, особенно касающихся извлечения отдельных символов, их перестановки и т.д. Если ABC использует строковые библиотеки .NET, у него есть все шансы выиграть в РАЗЫ.

У меня в общем то и нет иллюзий по поводу производительности FPC, на то много разных факторов. Не понятно другое, почему пару строк, по сути ни на что не влияющих, все таки влияют, Вдвое увеличивая скорость выполнения, как так то?
pro_berserk
новенький
 
Сообщения: 21
Зарегистрирован: 05.11.2013 14:02:33

Re: Требуется разъяснение Специалистов

Сообщение SSerge » 31.10.2017 17:07:26

Код: Выделить всё
{$mode objfpc}
uses sysutils;


var i,j,n:integer;
    s:double;
    tm,tm2:TTimeStamp;
begin
  tm:=DateTimeToTimeStamp(now);
  n := 10000;
  s := 0.0;
  for i:=1 to n do
    for j:=1 to n do
      s += 1.0/(i*j);
  tm2:=DateTimeToTimeStamp(now);
  writeln(tm2.time-tm.time);
end.


Result: 638..640

Код: Выделить всё
{$mode objfpc}
Uses sysutils;


var i,j,n:integer;
    s:double;
    tm,tm2:TTimeStamp;

function Milliseconds:LongInt;
begin
  result:=DateTimeToTimeStamp(now).time-tm.time;
end;

begin
  tm:=DateTimeToTimeStamp(now);
  n := 10000;
  s := 0.0;
  for i:=1 to n do
    for j:=1 to n do
      s += 1.0/(i*j);
  writeln(Milliseconds);
end.



Result:=638..646

32-х битный линукс, Free Pascal Compiler version 3.1.1 [2017/08/13] for i386
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Требуется разъяснение Специалистов

Сообщение MysticCoder » 31.10.2017 17:27:58

pro_berserk писал(а):Получаю среднее время выполнения - 265мс
Выношу код выше в отдельную функцию и вызываю её: Среднее время выполнения - 565мс

С чем это может быть связанно помогите разобраться пожалуйста...


кидай полный код первого и второго варианта без сокращений типа "Выношу код выше в отдельную функцию" ну и результаты соответственно, а то вдруг у тебя эта отдельная функция в незагруженной с диска библиотеке лежит, или выносишь криво...
MysticCoder
постоялец
 
Сообщения: 154
Зарегистрирован: 14.09.2013 00:20:28

Re: Требуется разъяснение Специалистов

Сообщение pro_berserk » 31.10.2017 17:35:57

SSerge писал(а):
Result:=638..646
32-х битный линукс, Free Pascal Compiler version 3.1.1 [2017/08/13] for i386

Windows 7 x64, FPC version 3.0.2 [2017/02/27] for x86_x64-win64-win32/win64
С Вашим кодом результат примерно тот же 565..580
А вот если сделать так:
Код: Выделить всё
var cur_t,ml,StartTime:TDateTime;
begin
  StartTime:=Time;
  n := 10000;
  s := 0.0;
  for i:=1 to n do
    for j:=1 to n do
      s += 1.0/(i*j);
   cur_t:=Time;
   ml:= cur_t-StartTime;
   WriteLn('Milliseconds: ',IntToStr(DateTimeToTimeStamp(ml).Time) );
  end;


Вся программа Result=277..297
Код: Выделить всё
program Project1;
uses
   Sysutils;

var cur_t,ml,StartTime:TDateTime;
    i,j,n:integer;
    s:double;
begin
  StartTime:=Time;
  n := 10000;
  s := 0.0;
  for i:=1 to n do
    for j:=1 to n do
      s += 1.0/(i*j);
   cur_t:=Time;
   ml:= cur_t-StartTime;
   WriteLn('Milliseconds: ',IntToStr(DateTimeToTimeStamp(ml).Time) );
   Readln;
end.

С вынесенной функцией: 560..590
Код: Выделить всё
program Project1;
uses
   Sysutils;

var cur_t,ml,StartTime:TDateTime;
    i,j,n:integer;
    s:double;

function Milliseconds:LongInt;
begin
  cur_t:=Time;
  ml:=cur_t-StartTime;
  Result:=DateTimeToTimeStamp(ml).Time;
end;
begin
  StartTime:=Time;
  n := 10000;
  s := 0.0;
  for i:=1 to n do
    for j:=1 to n do
      s += 1.0/(i*j);
   Writeln(Milliseconds);
   Readln;
end.


Специально делаю кучу переменных, для меня так нагляднее...
У вас нет необходимых прав для просмотра вложений в этом сообщении.
pro_berserk
новенький
 
Сообщения: 21
Зарегистрирован: 05.11.2013 14:02:33

Re: Требуется разъяснение Специалистов

Сообщение SSerge » 31.10.2017 17:53:14

pro_berserk писал(а):Вся программа


ваш код дал 639..642 на той же машине и компиляторе
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Требуется разъяснение Специалистов

Сообщение Лекс Айрин » 31.10.2017 17:59:46

Слишком хорошо и не получится.. Результат примерно одинаковый и, имхо, разница чисто в том, что PABC, заточен под одну систему, а fpc под несколько, поэтому в нем нет возможности использовать более быстрые, но менее кросс-платформенные варианты кода. И, если уж на то пошло, попробуй поиграться с оптимизацией.

pro_berserk писал(а):Не понятно другое, почему пару строк, по сути ни на что не влияющих, все таки влияют, Вдвое увеличивая скорость выполнения, как так то?


Реализация вложенных циклов сама по себе очень корявая и не только в паскале, но и в других языках. Это связано с тем, что у процессора только один счетчик циклов. Плюс, периодический сброс очереди выполнения программ. (при "тике" цикла, вызове функции, в условном переходе... ), плюс, периодическая подкачка данных в кеши процессора. По возможности, компилятор это все компенсирует, но не всегда получается.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Требуется разъяснение Специалистов

Сообщение MysticCoder » 31.10.2017 18:06:13

pro_berserk писал(а):С вынесенной функцией: 560..590

замени вызов Writeln(Milliseconds); на MyWriteln(Milliseconds);
Код: Выделить всё
procedure MyWriteLN(a : longint);
begin
  writeln(a);
end;       


и протесть еще раз. если поставишь бряк на Writeln(Milliseconds), нажмешь Ctrl-Alt-D, то увидишь, что перед тем как вызвать Milliseconds вызывается еще какая то функция от Writeln. Она то видимо и тормозит.
MysticCoder
постоялец
 
Сообщения: 154
Зарегистрирован: 14.09.2013 00:20:28

Re: Требуется разъяснение Специалистов

Сообщение pro_berserk » 31.10.2017 18:30:10

MysticCoder писал(а):и протесть еще раз. если поставишь бряк на Writeln(Milliseconds), нажмешь Ctrl-Alt-D, то увидишь, что перед тем как вызвать Milliseconds вызывается еще какая то функция от Writeln. Она то видимо и тормозит.

Признаться честно я хоть по образованию и программист, но как то в жизни не сложилось, поэтому занимаюсь этим делом больше любительски.
Разъясните пожалуйста куда смотреть? Я что то не заметил лишних вызовов.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
pro_berserk
новенький
 
Сообщения: 21
Зарегистрирован: 05.11.2013 14:02:33

Re: Требуется разъяснение Специалистов

Сообщение MysticCoder » 31.10.2017 18:34:40

pro_berserk писал(а):
MysticCoder писал(а):и протесть еще раз. если поставишь бряк на Writeln(Milliseconds), нажмешь Ctrl-Alt-D, то увидишь, что перед тем как вызвать Milliseconds вызывается еще какая то функция от Writeln. Она то видимо и тормозит.

Признаться честно я хоть по образованию и программист, но как то в жизни не сложилось, поэтому занимаюсь этим делом больше любительски.
Разъясните пожалуйста куда смотреть? Я что то не заметил лишних вызовов.


Лишних вызовов нет, потому что смотришь MyWriteln, посмотри Writeln.

Добавлено спустя 6 минут 16 секунд:
вообще если уж время замерять под виндой, то почему бы не пользоваться функцией NtQueryPerfomanceCounter совместно с NtQueryPerfomanceFrequency?
все ею меряют.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
MysticCoder
постоялец
 
Сообщения: 154
Зарегистрирован: 14.09.2013 00:20:28

Re: Требуется разъяснение Специалистов

Сообщение pro_berserk » 31.10.2017 18:45:39

MysticCoder писал(а):Лишних вызовов нет, потому что смотришь MyWriteln, посмотри Writeln.

Я правильно понял, что callq , это и есть вызов некой лишней fpc_get_output?

вообще если уж время замерять под виндой, то почему бы не пользоваться функцией NtQueryPerfomanceCounter совместно с NtQueryPerfomanceFrequency?
все ею меряют.

Так цели и не было, что то замерять. Цель понять почему у меня из-за добавления в алгоритм, операции вычитания двух дат, меняется скорость выполнения циклов вдвое, при чем в лучшую сторону. 560мс против 260мс. Вот что не понятно...
У вас нет необходимых прав для просмотра вложений в этом сообщении.
pro_berserk
новенький
 
Сообщения: 21
Зарегистрирован: 05.11.2013 14:02:33

Re: Требуется разъяснение Специалистов

Сообщение MysticCoder » 31.10.2017 18:51:49

pro_berserk писал(а):Я правильно понял, что callq , это и есть вызов некой лишней fpc_get_output?

да, оно и есть.

во втором случае так же идет вызов процедуры, на что тратится еще чуток времени, на подготовку стека и чего то еще. можно её сделать inline; будет быстрее.
ну это в теории, в данном случае вряд ли это "чуток времени" занимает больше 1 мс.
MysticCoder
постоялец
 
Сообщения: 154
Зарегистрирован: 14.09.2013 00:20:28

След.

Вернуться в Потрепаться

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 25

Рейтинг@Mail.ru