Vychází to stejně. Switch je realizovaný jako JMP s úplně stejným obsahem. Rozdíl v tom, že jedno je CALL a druhý JMP se moc neprojeví, protože optimalizer by CALL strčil na jinou úroveň kódu, třeba do toho push_back, který se skrývá za přiřazení do iterátoru, který v tomhle případě inlinoval. Dělá to podle toho, jak moc vyjde inlinovaný kód dlouhý, když je přes nějaký treshold, rozhodne se tam udělat CALL.
V tom kódu s UTF-8 se navíc rozvine ten cyklus. Kdybys to psal switchem, nejspíš bys to rozvíjel ručně, nebo bys tam ten cyklus nechal. Možná - ale nemám to ověřený - by překladač nějak usoudil, že může vygenerovat varianty toho cyklu podle spočítaného indexu, ale myslím si že ne, alespoň ne GCC. Na to takovou umělou inteligencí neoplývají.
Podmíněný skok je horší, než skok na spočítanou adresu
Ono je to složitější. Kdybych to měl srovna v pořadí od nejefektivnějšího tak to dopadne takto
1) skok na pevnou adresu
2) podmíněný skok který se podaří odhadnout
3) skok na dynamickou adresu
4) volání virtuální funkce
.
.
.
.
.
X) podmíněný skok, který se nepodařilo odhadnout.
- pokud budeš lámat nějaký mezinárodní, čínský text, pak ty podmíněné skoky dost zabijou performanci. Ale myslím si, že to bude znát i u nějakého českého textu
Nic takového neexistuje. Samozřejmě, pokud adresa není známa v určitém bodě, musí dekóder instrukcí čekat. Proto ta instrukce LEA pro výpočet začátku tabulky je s předstihem, aby jakmile je znám výsledek EAX, tak se mohlo pokračovat.
Nicméně se domnívám, že zahazování rozpracované větvě při špatném odhadu je mnohem náročnější pro CPU, než prostě počkat, dokud není výsledek znám. On, jakmile je výsledek znám, může se pokračovat v dekódování instrukcí a přitom to ještě neznamená, že by instrukce byla dokončena, tam je ještě nějaký cleanup a commit fáze, Prostě obecně je skok na vypočtenou adresu rychlejší, než špatně odhadnutý podmíněny skok.
Nic takového neexistuje? A co je to teda ta "indirect branch prediction" o které tady Intel píše? https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/speculative-execution-side-channel-mitigations.html
Ok, máš pravdu, nejsem znalec všech optimalizačních technik CPU. Vím jen, že branch prediction se sleduje hlavně u IFů.
Chápu ale pořád benefit v tom mít jedno místo, kde ti selže branch prediction je lepší, než jich mít víc. Tedy pokud dokážeš nahradit několik IFů jednou indirekcí, pořád je to win.
Ono není až tak důležité, kolik těch míst je. Ty počty skoků, pro které teď procesory zvládnou udržet predikční data jdou do tisíců (co jsem viděl testy). Daleko víc záleží na tom, jestli ty jednotlivé skoky mají predikovatelné chování. Nahradit jedno větvení se složitým vzorem několika jednoduššími se vyplatí.
U toho utf8 bude silně záviset na datech. Pravidelná čínština bude mít pravděpodobně jiné vzory než ascii se smajlíky. Bez profilování není takřka v lidských silách odhadnout, jak dobře je nějaký kus kódu predikovatelný.
Odstrašující příklad je std::variant. Standard říká, že visit má být O(1), takže tam musí být nějaká jump table dost podobná té vaší. Nestandardní implementace používají jednoduchý switch, který sice není O(1), ale v praktickém nasazení ten standardní přístup drtí tak, že to až hezké není. Ona je ta jump table i dost brutální neprůhledná bariéra pro optimalizátor.
Velké používání instrukcí
call *(%rcx,%rax,8)
jsem viděl právě na std::variant v gcc 11+.
Samozřejmě mě zajímalo, jak se visit přeloží a přeloží se právě přes tento call. Dříve jsem tyhle cally potkával jen u virtuálních metod, takže jsem měl chvíli dojem, že tam mají vtable. Jo byly nějaké starší implementace, které používali switch-case
Intenzivně se zabývám programováním zejména v jazyce C++. Vyvíjím vlastní knihovny, vzory, techniky, používám šablony, to vše proto, aby se mi usnadnil život při návrhu aplikací. Pracoval jsem jako programátor ve společnosti Seznam.cz. Nyní jsem se usadil v jednom startupu, kde vyvíjím serverové komponenty a informační systémy v C++
Přečteno 50 890×
Přečteno 23 805×
Přečteno 22 794×
Přečteno 20 804×
Přečteno 17 676×