Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Inline функции [WinXP]


Страницы:   1 2 3

Kos[UFO] ©   (2006-08-16 15:17:00) 

Умеет ли компилятор BDS создавать встраиваемые функции и насколько это эффективно?


Джо   (2006-08-16 22:18:00) [21]

Мой вывод таков. Inline полезно для функций с большим количеством параметров, особенно для функций, вызываемых многократно в цикле. Банально, но так :)


Джо   (2006-08-16 22:17:00) [22]

> Чапаев

И в твоем листинге push'и идут уже внутри функции, т.е, при вызове FloatToStr, которая не объявлена как inline. Соответственно, никакого отношения к сабжу не имеет.


Джо   (2006-08-16 22:15:00) [23]

> [19] Чапаев ©   (16.08.06 22:12)
> Без инлайна работа со стеком значительно интенсивнее. Но
> всё же и говорить, что при использовании инлайна в стек
> ничего не кладётся, не приходится...

А я и не говорил. Я говорил только ([11]): "Push забывать не стоит". :-p


Чапаев   (2006-08-16 22:12:00) [24]

Без инлайна работа со стеком значительно интенсивнее. Но всё же и говорить, что при использовании инлайна в стек ничего не кладётся, не приходится...


Джо   (2006-08-16 22:02:00) [25]

> [17] Чапаев ©   (16.08.06 22:00)

Теперь сравни без inline:

Unit24.pas.33: Proc (10,20,30,40,50,60,70,80);
00457FE0 6A00             push $00
00457FE2 6A0A             push $0a
00457FE4 6A00             push $00
00457FE6 6A14             push $14
00457FE8 6A00             push $00
00457FEA 6A1E             push $1e
00457FEC 6A00             push $00
00457FEE 6A28             push $28
00457FF0 6A00             push $00
00457FF2 6A32             push $32
00457FF4 6A00             push $00
00457FF6 6A3C             push $3c
00457FF8 6A00             push $00
00457FFA 6A46             push $46
00457FFC 6A00             push $00
00457FFE 6A50             push $50
00458000 E84BFFFFFF       call Proc


Чапаев   (2006-08-16 22:00:00) [26]


Unit1.pas.35: A(1,2,3,4.5,6.7);
00457DF8 8D55FC           lea edx,[ebp-$04]
00457DFB B801000000       mov eax,$00000001
00457E00 E8D707FBFF       call IntToStr
00457E05 8B45FC           mov eax,[ebp-$04]
00457E08 E82745FDFF       call ShowMessage
00457E0D 8D55F8           lea edx,[ebp-$08]
00457E10 B802000000       mov eax,$00000002
00457E15 E8C207FBFF       call IntToStr
00457E1A 8B45F8           mov eax,[ebp-$08]
00457E1D E81245FDFF       call ShowMessage
00457E22 8D55F4           lea edx,[ebp-$0c]
00457E25 B803000000       mov eax,$00000003
00457E2A E8AD07FBFF       call IntToStr
00457E2F 8B45F4           mov eax,[ebp-$0c]
00457E32 E8FD44FDFF       call ShowMessage
00457E37 6801400000       push $00004001
00457E3C 6800000090       push $90000000
00457E41 6A00             push $00

00457E43 8D45F0           lea eax,[ebp-$10]
00457E46 E8411CFBFF       call FloatToStr
00457E4B 8B45F0           mov eax,[ebp-$10]
00457E4E E8E144FDFF       call ShowMessage
00457E53 6801400000       push $00004001
00457E58 68666666D6       push $d6666666
00457E5D 6866666666       push $66666666
//тут был Сотона!
00457E62 8D45EC           lea eax,[ebp-$14]
00457E65 E8221CFBFF       call FloatToStr
00457E6A 8B45EC           mov eax,[ebp-$14]
00457E6D E8C244FDFF       call ShowMessage


Джо   (2006-08-16 21:56:00) [27]

> [15] Чапаев ©   (16.08.06 21:46)

Снова проверяем:

procedure Proc (A,B,C,D,E,F,G,H: Int64); inline;
begin
 ShowMessageFmt ('%d,%d,%d,%d,%d,%d,%d,%d',[A,B,C,D,E,F,G,H]);
end;


Не запихиваются :)


Чапаев   (2006-08-16 21:46:00) [28]

> Параметры в стек не запихиваются.

Флоаты таки дополнительно запихиваются в стек, просто в твоём примере компилятор мудро догадался, что последние четыре параметра ни к чему.


Джо   (2006-08-16 21:33:00) [29]

> [12] jack128 ©   (16.08.06 21:26)
> они и в случае inline функций через стек передаются.

Нет, только что проверил, не передаются. Вот, обычная "болванка", чтобы не через регистры:
procedure A (I: Integer; B: Integer; H: Integer; D: Double; F: Double); inline;
begin
 ShowMessage (IntToStr(I));
end;

Параметры в стек не запихиваются.


Чапаев   (2006-08-16 21:29:00) [30]

> они и в случае inline функций через стек передаются

Да? Каюсь, не исследовал код. Но имхо копию параметров в стек делать нет смысла в случае инлайнов...


jack128   (2006-08-16 21:26:00) [31]

Чапаев ©   (16.08.06 21:22) [10]
При том, что иногда приходится параметры и через стек передавать.

они и в случае inline функций через стек передаются.


Джо   (2006-08-16 21:24:00) [32]

> [8] Anatoly Podgoretsky ©   (16.08.06 21:12)
> Чапаев ©   (16.08.06 20:54) [6]
> Причем тут это, вне зависимости от количества параметров,
> обе эти команды выполняются одинаковое количество тактов.

Push забывать не стоит.


Чапаев   (2006-08-16 21:22:00) [33]

> Причем тут это

При том, что иногда приходится параметры и через стек передавать.


Джо   (2006-08-16 21:22:00) [34]

> [5] Kos[UFO] ©   (16.08.06 20:49)
> Джо, о каких исключениях Вы говорите?


The inline directive is a suggestion to the compiler. There is no guarantee the compiler will inline a particular routine, as there are a number of circumstances where inlining cannot be done. The following list shows the conditions under which inlining does or does not occur:

* Inlining will not occur on any form of late-bound method. This includes virtual, dynamic, and message methods.
* Routines containing assembly code will not be inlined.
* Constructors and destructors will not be inlined.
* The main program block, unit initialization, and unit finalization blocks cannot be inlined.
* Routines that are not defined before use cannot be inlined.
* Routines that take open array parameters cannot be inlined.
* Code can be inlined within packages, however, inlining never occurs across package boundaries.
* No inlining will be done between units that are circularly dependent. This included indirect circular dependencies, for example, unit A uses unit B, and unit B uses unit C which in turn uses unit A. In this example, when compiling unit A, no code from unit B or unit C will be inlined in unit A.
* The compiler can inline code when a unit is in a circular dependency, as long as the code to be inlined comes from a unit outside the circular relationship. In the above example, if unit A also used unit D, code from unit D could be inlined in A, since it is not involved in the circular dependency.
* If a routine is defined in the interface section and it accesses symbols defined in the implementation section, that routine cannot be inlined.
* In Delphi.NET, routines in classes cannot be inlined if they access members with less (i.e. more restricted) visibility than the method itself. For example, if a public method accesses private symbols, it cannot be inlined.
* If a routine marked with inline uses external symbols from other units, all of those units must be listed in the uses statement, otherwise the routine cannot be inlined.
Pr* ocedures and functions used in conditional expressions in while-do and repeat-until statements cannot be expanded inline.
* Within a unit, the body for an inline function should be defined before calls to the function are made. Otherwise, the body of the function, which is not known to the compiler when it reaches the call site, cannot be expanded inline.
If you modify the implementation of an inlined routine, you will cause all units that use that function to be recompiled. This is different from traditional rebuild rules, where rebuilds were triggered only by changes in the interface section of a unit.

(c) Delphi Help, "Calling Procedures and Functions" topic.


Anatoly Podgoretsky   (2006-08-16 21:12:00) [35]

Чапаев ©   (16.08.06 20:54) [6]
Причем тут это, вне зависимости от количества параметров, обе эти команды выполняются одинаковое количество тактов.


Anatoly Podgoretsky   (2006-08-16 21:11:00) [36]

Что же функция такая, которая вызвается миллиарды раз и ничего не делает.


Чапаев   (2006-08-16 20:54:00) [37]

> Экономия на только на call и ret, то есть практически два
> такта.

Это смотря какой список параметров...


Kos[UFO]   (2006-08-16 20:49:00) [38]

И один такт может улучшить ситуацию, когда это критично. А разве раньше Delphi умел это делать?
Джо, о каких исключениях Вы говорите?


Anatoly Podgoretsky   (2006-08-16 19:44:00) [39]

Экономия на только на call и ret, то есть практически два такта.


pasha_golub   (2006-08-16 16:25:00) [40]


> и насколько это эффективно?

На сегодняшних-то вычислительный мощностях. Не думаю, что стоит.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо