GNU/Linux >> Znalost Linux >  >> Linux

Jak vyprázdnit mezipaměť CPU pro oblast adresního prostoru v Linuxu?

Toto je pro ARM.

GCC poskytuje __builtin___clear_cache což dělá by měl provést syscall cacheflush . Může však mít své výhrady.

Důležitá věc je, že Linux poskytuje systémové volání (specifické pro ARM) k vyprázdnění mezipaměti. Jak používat toto systémové volání, můžete zkontrolovat Android/Bionic flushcache. Nejsem si však jistý, jaké záruky Linux poskytuje, když jej nazýváte, nebo jak je implementován prostřednictvím svých vnitřních funkcí.

Tento blogový příspěvek Mezipaměti a samomodifikující kód může pomoci dále.


Podívejte se na tuto stránku pro seznam dostupných metod proplachování v linuxovém jádře:https://www.kernel.org/doc/Documentation/cachetlb.txt

Proplachování mezipaměti a TLB pod Linuxem. David S. Miller

Existuje sada funkcí proplachování rozsahu

2) flush_cache_range(vma, start, end);
   change_range_of_page_tables(mm, start, end);
   flush_tlb_range(vma, start, end);

3) void flush_cache_range(struct vm_area_struct *vma, dlouhý začátek bez znaménka, dlouhý konec bez znaménka)

Here we are flushing a specific range of (user) virtual
addresses from the cache.  After running, there will be no
entries in the cache for 'vma->vm_mm' for virtual addresses in
the range 'start' to 'end-1'.

Můžete také zkontrolovat implementaci funkce - http://lxr.free-electrons.com/ident?a=sh;i=flush_cache_range

Například v paži - http://lxr.free-electrons.com/source/arch/arm/mm/flush.c?a=sh&v=3.13#L67

 67 void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 68 {
 69         if (cache_is_vivt()) {
 70                 vivt_flush_cache_range(vma, start, end);
 71                 return;
 72         }
 73 
 74         if (cache_is_vipt_aliasing()) {
 75                 asm(    "mcr    p15, 0, %0, c7, c14, 0\n"
 76                 "       mcr     p15, 0, %0, c7, c10, 4"
 77                     :
 78                     : "r" (0)
 79                     : "cc");
 80         }
 81 
 82         if (vma->vm_flags & VM_EXEC)
 83                 __flush_icache_all();
 84 }

V x86 verzi Linuxu také můžete najít funkci void clflush_cache_range(void *vaddr, unsigned int size) který se používá pro účely vyprázdnění rozsahu mezipaměti. Tato funkce se spoléhá na CLFLUSH nebo CLFLUSHOPT instrukce. Doporučil bych zkontrolovat, zda je váš procesor skutečně podporuje, protože teoreticky jsou volitelné.

CLFLUSHOPT je slabě nařízeno. CLFLUSH byl původně specifikován jako pořadí pouze podle MFENCE , ale všechny CPU, které to implementují, tak činí se silným řazením wrt. píše a další CLFLUSH instrukce. Intel se rozhodl přidat novou instrukci (CLFLUSHOPT ) namísto změny chování CLFLUSH a aktualizovat manuál, aby bylo zaručeno, že budoucí CPU budou implementovat CLFLUSH jak důrazně nařízeno. Pro toto použití byste měli MFENCE po použití kteréhokoli z nich, abyste se ujistili, že propláchnutí je provedeno před jakýmkoli načtením z vašeho benchmarku (nejen obchodů).

Ve skutečnosti x86 poskytuje ještě jednu instrukci, která by mohla být užitečná:CLWB . CLWB vyprázdní data z mezipaměti do paměti, aniž by je (nezbytně) vyprázdnila, takže je ponechá čistá, ale stále uložená v mezipaměti. clwb na SKX vyhazuje jako clflushopt , ačkoli

Všimněte si také, že tyto pokyny jsou koherentní v mezipaměti. Jejich spuštění ovlivní všechny mezipaměti všech procesorů (procesorových jader) v systému.

Všechny tyto tři pokyny jsou dostupné v uživatelském režimu. Můžete tedy použít assembler (nebo vnitřní prvky jako _mm_clflushopt ) a vytvořte si vlastní void clflush_cache_range(void *vaddr, unsigned int size) ve vaší aplikaci v uživatelském prostoru (nezapomeňte si však před skutečným použitím ověřit jejich dostupnost).

Pokud tomu dobře rozumím, je v tomto ohledu mnohem obtížnější uvažovat o ARM. Rodina procesorů ARM je mnohem méně konzistentní než rodina procesorů IA-32. Můžete mít jeden ARM s plnohodnotnými mezipamětmi a další zcela bez mezipamětí. Navíc mnoho výrobců může používat přizpůsobené MMU a MPU. Je tedy lepší uvažovat o nějakém konkrétním modelu procesoru ARM.

Bohužel to vypadá, že bude téměř nemožné provést nějaký rozumný odhad času potřebného k vyprázdnění některých dat. Tento čas je ovlivněn příliš mnoha faktory včetně počtu vyprázdněných řádků mezipaměti, neuspořádaného provádění instrukcí, stavu TLB (protože instrukce bere jako argument virtuální adresu, ale mezipaměti používají fyzické adresy), počtu CPU v systému, skutečné zatížení, pokud jde o operace s pamětí na ostatních procesorech v systému, a kolik řádků z rozsahu je skutečně ukládáno do mezipaměti procesory a nakonec podle výkonu CPU, paměti, řadiče paměti a paměťové sběrnice. Ve výsledku si myslím, že doba provádění se bude v různých prostředích a při různém zatížení výrazně lišit. Jediným rozumným způsobem je měřit dobu proplachu na systému a se zátěží podobnou cílovému systému.

A poslední poznámka, nepleťte si mezipaměti paměti a TLB. Obě jsou to cache, ale organizované různými způsoby a sloužící různým účelům. TLB ukládá do mezipaměti pouze naposledy použité překlady mezi virtuálními a fyzickými adresami, ale ne data, na která tyto adresy odkazují.

A TLB není koherentní, na rozdíl od paměťových mezipamětí. Buďte opatrní, protože vyprázdnění položek TLB nevede k vyprázdnění příslušných dat z mezipaměti.


Linux
  1. Jak používat příkaz sed pro Linux

  2. Jak nastavit IP adresu z C v linuxu

  3. Jak získat rychlost hodin procesoru ARM v Linuxu?

  1. Linux:Jak najít ovladač zařízení používaný pro zařízení?

  2. Linux – Jak dát Ram do mezipaměti souborového systému?

  3. Jak zjistit IP adresu brány v Linuxu

  1. Linux – Jak získat adresu IPv4 pro rozhraní z /proc?

  2. Jak najít aplikaci pro typ mime v systému Linux?

  3. Jak vyčistit mezipaměti používané linuxovým jádrem