GNU/Linux >> Znalost Linux >  >> Linux

Proč tato smyčka zpoždění začne běžet rychleji po několika iteracích bez spánku?

Po 26 iteracích Linux zvýší rychlost procesoru na maximální takt, protože váš proces několikrát za sebou použije plný časový úsek.

Kdybyste zkontrolovali počítadla výkonu místo času nástěnných hodin, viděli byste, že cykly taktování jádra na smyčku zpoždění zůstaly konstantní, což potvrzuje, že jde pouze o efekt DVFS (který všechny moderní CPU používají k tomu, aby běžel s vyšší spotřebou energie). efektivní frekvence a napětí po většinu času).

Pokud byste testovali na Skylake s podporou jádra pro nový režim správy napájení (kde hardware přebírá plnou kontrolu nad rychlostí hodin), náběh by probíhal mnohem rychleji.

Pokud jej necháte chvíli běžet na procesoru Intel s Turbo, pravděpodobně uvidíte, že se čas na iteraci opět mírně zvýší, jakmile tepelné limity vyžadují, aby se rychlost hodin snížila zpět na maximální udržitelnou frekvenci. (Viz Proč si můj CPU nemůže udržet špičkový výkon v HPC, kde najdete další informace o Turbo, které umožňuje CPU běžet rychleji, než dokáže udržet při vysokém pracovním zatížení.)

Představujeme 00 zabraňuje linuxovému regulátoru frekvence CPU zvýšit rychlost hodin, protože proces negeneruje 100% zatížení ani při minimální frekvenci. (Tj. heuristika jádra rozhodne, že CPU běží dostatečně rychle na zátěž, která na něm běží.)

komentáře k jiným teoriím :

re:Davidova teorie, že potenciální kontext se změní z 19 mohlo by znečišťovat mezipaměti:Obecně to není špatný nápad, ale nepomáhá to vysvětlit tento kód.

Znečištění mezipaměti / TLB není pro tento experiment vůbec důležité . V okně časování není v podstatě nic, co by se dotýkalo paměti, kromě konce zásobníku. Většinu času tráví v malé smyčce (1 řádek instrukční mezipaměti), která se dotýká pouze jednoho 27 zásobníkové paměti. Jakékoli potenciální znečištění mezipaměti během 31 je pro tento kód nepatrný zlomek času (skutečný kód se bude lišit)!

Podrobněji pro x86:

Volání na 49 samo o sobě může chybět v mezipaměti, ale vynechání mezipaměti načtení kódu zpožďuje měření času spuštění, spíše než aby bylo součástí toho, co se měří. Druhé volání na 57 nebude téměř nikdy zpožděn, protože by měl být stále horký v mezipaměti.

60 funkce může být v jiném řádku mezipaměti než 72 (protože gcc označuje 89 jako "studený", takže se méně optimalizuje a umístí s jinými studenými funkcemi/daty). Můžeme očekávat jedno nebo dvě vynechání instrukční mezipaměti. Pravděpodobně jsou však stále na stejné stránce 4k, takže 98 spustilo potenciální vynechání TLB před vstupem do časované oblasti programu.

gcc -O0 zkompiluje kód OP do něčeho takového (Godbolt Compiler explorer):ponechá čítač smyček v paměti na zásobníku.

Prázdná smyčka udržuje čítač smyčky v paměti zásobníku, takže na typickém procesoru Intel x86 smyčka běží jednou iterací za ~6 cyklů na CPU IvyBridge OP, díky latenci předávání úložiště, která je součástí 106 s cílem paměti (čtení-upravování-zápis). 113 je 600 000 cyklů, což dominuje příspěvku maximálně několika chyb v mezipaměti (~200 cyklů každé pro chyby při načítání kódu, které brání vydávání dalších instrukcí, dokud nejsou vyřešeny).

Spuštění mimo pořadí a přesměrování úložiště by mělo většinou skrýt potenciální chybějící mezipaměť při přístupu k zásobníku (jako součást 129 instrukce).

I kdyby byl čítač smyček uložen v registru, 100 000 cyklů je hodně.


Volání na číslo 133 může nebo nemusí mít za následek přepnutí kontextu. Pokud ano, bude to trvat déle, než kdyby ne.


Linux
  1. Proč Unixový čas začíná na 1970-01-01?

  2. Proč Plymouth začíná tak pozdě?

  3. Proč Tomcat pracuje s portem 8080, ale ne s 80?

  1. Proč tento kód selhává při zapnuté randomizaci adres?

  2. Jak spustit příkaz na pozadí se zpožděním?

  3. Proč se připojení připojení souboru po odpojení nezdaří pomocí ENOENT?

  1. Mám se pokusit „vyvážit“ svá vlákna nebo to dělá linux?

  2. PHP-FPM se po restartu automaticky nespustí

  3. Proč se tento příkaz ldapadd ukončí s chybou Neplatná syntaxe?