Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Milfaus 01. 09. 2017, 20:59:13
-
Ahoj,
rád bych se zeptal, jak je to na linuxu s voláním knihovní funkce přilinkované k programu?
Nějak mi to nende vygooglovat, nevypadávají relevantní výsledky.
Mám program, který přeložím:
gcc ..... knihovna.a
Dochází při volání knihovní funkce ke zpoždění?
Resp. penalizace cca ~500 taktů jako na Widlows?
-
Ahoj,
rád bych se zeptal, jak je to na linuxu s voláním knihovní funkce přilinkované k programu?
Nějak mi to nende vygooglovat, nevypadávají relevantní výsledky.
Mám program, který přeložím:
gcc ..... knihovna.a
Dochází při volání knihovní funkce ke zpoždění?
Resp. penalizace cca ~500 taktů jako na Widlows?
Statická knihovna se přilinkuje celá přímo do binárky, tam ke zpoždění nedochází.
-
Statická knihovna se přilinkuje celá přímo do binárky, tam ke zpoždění nedochází.
Díky za info ohledně toho zpoždění!
-
Mohl byste dát zdroj ohledně informací o zpoždění na Windows? Pokud se nejedná o delay loaded imports, zpoždění by nemělo být žádné.
-
zpoždění by nemělo být žádné.
C# při volání externích knihoven načtených přes dllimport a P/Invoke je údajně penalizováno (poměrně logicky).
Dokonce jsou nějaké postupy, jak to trochu zkrotit.
Hodnoty sem viděl v dokumentaci přímo od MS, ale obratem ruky je nejspíš nedohledám.
-
Aha, máte na mysli přechod z managed do unmanaged kódu (tam penalizace je). Z úvodního příspěvku jsen nabyl dojmu, že mluvíte o volání funkcí v rámci C/C++ (nativního kódu).
-
Jojo, mě právě zajímalo, jak je to u linuxu.
-
Jojo, mě právě zajímalo, jak je to u linuxu.
"U linuxu" je to v takovém případě stejně jako všude jinde.
-
Tak funkce ze statické knihovny (.a) jsou přilinkované ve výsledném bináru, ne?
A samotné volání funkce v c je (zhruba):
1. Naskládání parametrů (od posledního k prvnímu) na zásobník (push <parametr1>, push ...).
2. Volání funkce (call <adresa funkce>)
(pokud není kompilátor požádán o "inlajnizaci" (od c99 tuším))
Proč by to v linuxu mělo být jinak?
-
Mícháte zde dohromady několik nesouvisejících věcí. Volání knihovní funkce z "dřevních" jazyků jako C(++), Fortran atp. není zatíženo žádnou režií. Na příslušná místa se nasází parametry volané funkce a procesor pak odskočí na adresu, kde kód volané funkce začíná. Rozdíl mezi staticky a dynamicky linkovanou knihovnou je jen v tom, že u dynamicky linkovaných knihoven je nejdřív nutné zjistit, kde v paměti se kód volané funkce nachází. To se provede buď hned při spuštění programu nebo v okamžiku, kdy se ta funkce zavolá. Provede se to ale vždy jen jednou. Staticky linkované knihovny se stanou součástí zkompilované binárky a vše se tedy může zařídit už při překladu.
Režie .NET spojená s voláním nativního kódu je zcela nesouvisející problém. Pokud něco podobného umožňuje Mono nebo .NET Core, čekal bych nějaký overhead i na Linuxu.
-
Volání knihovní funkce z "dřevních" jazyků jako C(++), Fortran atp. není zatíženo žádnou režií. Na příslušná místa se nasází parametry volané funkce a procesor pak odskočí na adresu, kde kód volané funkce začíná. Rozdíl mezi staticky a dynamicky linkovanou knihovnou je jen v tom, že u dynamicky linkovaných knihoven je nejdřív nutné zjistit, kde v paměti se kód volané funkce nachází. To se provede buď hned při spuštění programu nebo v okamžiku, kdy se ta funkce zavolá. Provede se to ale vždy jen jednou. Staticky linkované knihovny se stanou součástí zkompilované binárky a vše se tedy může zařídit už při překladu.
Rozdíl je i v tom, že volání do dynamické knihovny je nepřímé volání přes ukazatel na funkci. Volání do statické knihovny má tu adresu přímo v kódu. Znamená to jedno čtení z paměti navíc. Starší procesory tam měly i problém s predikcí větvení, takže nepřímé volání znamenalo vyprázdnění pipeline a zdržení v desítkách taktů. Novější už to zvládají predikovat. Pořád je to ale jeden potenciální cache miss navíc. Je to podobné rozdílu mezi virtuální a nevirtuální metodou.
Ale samozřejmě pro většinu normálních funkcí, které něco rozumného dělají, je ten rozdíl zanedbatelný.
-
Děkuji za vyčerpávající odpověď!