Hlavní navigace

Ubuntu 24.04 LTS zlepší profilování zapnutím ukazatele rámců

14. 12. 2023

Sdílet

Tachometr rychlost speedtest Autor: Depositphotos

Společnost Canonical se rozhodla, že počínaje verzí Ubuntu 24.04 LTS bude balíček GNU Compiler Collection (GCC) ve výchozím nastavení povolovat ukazatele rámce pro 64bitové platformy. Většina balíčků v Ubuntu bude znovu sestavena s povolenými ukazateli rámce, což usnadní jejich profilování a následnou optimalizaci.

Vývojáři už změnu testují a zdá se, že její praktický dopad na výkon je zanedbatelný. Povolil jsem ukazatele rámce pro Javu a glibc a studoval jsem režii procesoru při této změně, která je obvykle menší než 1 % a obvykle se blíží nule, takže je těžké ji vůbec změřit. Ukazatele rámců umožňují úplnější profilování CPU a profilování mimo CPU. Zlepšení výkonu, které mohou přinést, daleko převyšují relativně malou ztrátu výkonu, řekl Brendan Gregg, odborník na výkon počítačů.

Procesor při svém běhu do jednoho z registrů ukládá ukazatel rámce při volání funkce. Pokud ho ale funkce nevyužívá, je možné kompilátoru povolit využití tohoto registru jako univerzálního úložiště. To dokáže zefektivnit některé rutiny, ovšem za cenu nemožnosti jejich ladění.

Taková výměna je výhodná na 32bitových platformách, kde je registrů málo. Kód má k dispozici jen osm registrů, z čehož jeden je využit jako ukazatel zásobníku a druhý jako ukazatel rámce. Zvýšení počtu dostupných univerzálně použitelných registrů ze šesti na sedm tak může být významné. Naopak u 64bitových systémů je registrů mnohem víc a efekt jednoho registru navíc je zanedbatelný a nestojí za ztrátu možnosti program ladit a profilovat.

Ukazatele rámců totiž hrají klíčovou roli při zjednodušování procesu sledování zásobníku během profilování. Jejich výchozí povolení v kompilovaných binárkách zajišťuje vývojářům okamžitý přístup k přehlednějším a přesnějším datům pro analýzu výkonu bez nutnosti další konfigurace.

Našli jste v článku chybu?
  • Aktualita je stará, nové názory již nelze přidávat.
  • 16. 12. 2023 8:29

    atomicfall

    Chápu to správně, že pokud se kód dá optimalizovat tak, že se "inljajnují" těla všech funkcí, tak se dá EBP použít pro jiný účel neż uchování stavu rámců? Jak se pak vrátím zpátky z funkce main(), která v programu v Céčku musí být, když jsem ztratil informaci o pointeru na poslední rámec? Nebo se to uloží jako proměnná na stack? A co volání funkcí ze (standardních) knihoven?

    16. 12. 2023, 08:34 editováno autorem komentáře

  • 16. 12. 2023 13:57

    miho

    Z main (pokud neni volana rekurentne - C to umoznuje) se "nevracis", na konci (pri pruchodu } nebo return) se vola syscall sys_exit. Pokud se funkce inlinuje, tak se de facto nevola, takze nevznikne novy ramec. Co se deje pri volani funkce je zavisle na architekture a ABI. Na x86 CALL ulozi navratovou adresu na zasobnik. Vsechny ostatni registry jejichz hodnotu chces uchovat si musis explicitne PUSHnout. Proto neni jedinou rezii -fnoomit-frame-pointer zabrani jednoho registru (jak by se zdalo ze zpravicky) ale jeste navic jeden PUSH pri volani a jeden POP pri navratu.

  • 17. 12. 2023 8:05

    Wasper

    Pardon, ale to není tak úplně pravda. Ani sys_exit() to volat nemůže, ono se tam docela dobře může nacházet docela dost cleanupu. (atexit() např.)

    int main() { return 1; }

    (gdb) disass main
    Dump of assembler code for function main:
    0x0000000000400620 <+0>: push rbp
    0x0000000000400621 <+1>: mov rbp,rsp
    0x0000000000400624 <+4>: mov eax,0x1
    0x0000000000400629 <+9>: pop rbp
    0x000000000040062a <+10>: ret
    End of assembler dump.

    resp -O3 -fomit-frame-pointer

    (gdb) disass main
    Dump of assembler code for function main:
    0x00000000004004c0 <+0>: mov eax,0x1
    0x00000000004004c5 <+5>: ret
    End of assembler dump.

Byl pro vás článek přínosný?

Autor zprávičky

Petr Krčmář pracuje jako šéfredaktor serveru Root.cz. Studoval počítače a média, takže je rozpolcen mezi dva obory. Snaží se dělat obojí, jak nejlépe umí.