HugePages'in Avantajları ve Dezavantajları

HugePages'in Avantajları ve Dezavantajları

Ders öğrencileri için hazırlanan makalenin tercümesi "Linux Yöneticisi".

Daha önce Hugepages'in Linux üzerinde nasıl test edilip etkinleştirileceğinden bahsetmiştim.
Bu makale yalnızca Hugepages'i kullanacak bir yeriniz varsa yararlı olacaktır. Hugepages'in üretkenliği sihirli bir şekilde artıracağı ihtimaline kanan birçok insanla tanıştım. Ancak büyük sayfalama karmaşık bir konudur ve yanlış kullanıldığında performansı düşürebilir.

Bölüm 1: Linux'ta büyük sayfaların etkinleştirildiğini doğrulama (orijinal burada)

sorun:
Sisteminizde HugePages'in etkin olup olmadığını kontrol etmeniz gerekir.

Çözüm:
Oldukça basit:

cat /sys/kernel/mm/transparent_hugepage/enabled

Bunun gibi bir şey alacaksınız:

always [madvise] never

Mevcut seçeneklerin bir listesini göreceksiniz (her zaman, madvise, asla) ve şu anda etkin olan seçenek parantez içine alınacaktır (varsayılan olarak) delirmek).

delirmek anlamına gelir transparent hugepages yalnızca büyük sayfaları açıkça talep eden bellek alanları için etkindir. çılgın(2).

her zaman anlamına gelir transparent hugepages tüm işlemler için her zaman etkindir. Bu genellikle performansı artırır, ancak birçok işlemin az miktarda bellek tükettiği bir kullanım durumunuz varsa, genel bellek yükü önemli ölçüde artabilir.

asla anlamına gelir transparent hugepages madvise kullanılarak istendiğinde bile dahil edilmeyecektir. Daha fazlasını öğrenmek için iletişime geçin belgeleme Linux çekirdekleri.

Varsayılan değer nasıl değiştirilir

opsiyon 1: Doğrudan değiştir sysfs (yeniden başlatmanın ardından parametre varsayılan değerine dönecektir):

echo always >/sys/kernel/mm/transparent_hugepage/enabled
echo madvise >/sys/kernel/mm/transparent_hugepage/enabled
echo never >/sys/kernel/mm/transparent_hugepage/enabled

opsiyon 2: Çekirdeği değiştirilmiş bir yapılandırmayla yeniden derleyerek sistem varsayılanını değiştirin (bu seçenek yalnızca özel bir çekirdek kullanıyorsanız önerilir):

  • Her zaman varsayılan olarak ayarlamak için şunu kullanın:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Madvise'yi varsayılan olarak ayarlamak için şunu kullanın:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

Bölüm 2: HugePages'in Avantajları ve Dezavantajları

Hugepages'i kullanmanın avantajlarını, dezavantajlarını ve olası tuzaklarını seçerek açıklamaya çalışacağız. Teknolojik açıdan karmaşık ve bilgiçlik taslayan bir makalenin, Hugepages'in her derde deva olduğunu düşünme yanılgısına kapılan insanlar için anlaşılması muhtemelen zor olacağından, basitlik uğruna doğruluğu feda edeceğim. Pek çok konunun gerçekten karmaşık ve dolayısıyla büyük ölçüde basitleştirilmiş olduğunu akılda tutmakta fayda var.

Lütfen Linux çalıştıran 64 bit x86 sistemlerden bahsettiğimizi ve neredeyse tüm modern Linux'larda olduğu gibi sistemin şeffaf büyük sayfaları desteklediğini varsaydığımı (çünkü büyük sayfaların üzerine yazılmaması bir dezavantaj değildir) unutmayın. çevre.

Aşağıdaki bağlantılara daha fazla teknik açıklama ekleyeceğim.

Sanal bellek

Eğer bir C++ programcısıysanız, bellekteki nesnelerin belirli adresleri (işaretçi değerleri) olduğunu bilirsiniz.

Ancak bu adreslerin mutlaka bellekteki fiziksel adresleri (RAM adresleri) yansıtması gerekmez. Sanal bellekteki adresleri temsil ederler. İşlemcide, çekirdeğin sanal belleği fiziksel bir konumla eşleştirmesine yardımcı olan özel bir MMU (bellek yönetim birimi) modülü bulunur.

Bu yaklaşımın birçok avantajı vardır, ancak en önemlileri şunlardır:

  • Performans (çeşitli nedenlerden dolayı);
  • Program izolasyonu, yani hiçbir programın başka bir programın belleğinden okuma yapamamasıdır.

Sayfalar nedir?

Sanal bellek sayfalara bölünmüştür. Her bir sayfa belirli bir fiziksel belleğe işaret eder, RAM'deki bir alana işaret edebilir veya video kartı gibi fiziksel bir cihaza atanmış bir adrese işaret edebilir.

İlgilendiğiniz sayfaların çoğu ya RAM'e işaret eder ya da değiştirilir, yani sabit sürücünüzde veya SSD'de depolanırlar. Çekirdek, her sayfanın fiziksel düzenini yönetir. Sahte bir sayfaya erişilirse, çekirdek, belleğe erişmeye çalışan iş parçacığını durdurur, sayfayı sabit sürücüden/SSD'den RAM'e okur ve ardından iş parçacığını yürütmeye devam eder.

Bu işlem akış açısından şeffaftır, yani doğrudan HDD/SSD'den okunması gerekmemektedir. Normal sayfaların boyutu 4096 bayttır. Büyük sayfaların boyutu 2 megabayttır.

Çeviri-ilişkili tampon (TLB)

Bir program hafızanın bir sayfasına eriştiğinde, CPU'nun hangi fiziksel sayfadan veri okuyacağını bilmesi gerekir (yani sanal bir adres haritasına sahip olması).

Çekirdek, kullanılan sayfalara ilişkin tüm bilgileri içeren bir veri yapısına (sayfa tablosu) sahiptir. Bu veri yapısını kullanarak sanal bir adresi fiziksel bir adrese eşleyebilirsiniz.

Ancak sayfa tablosu oldukça karmaşık ve yavaş olduğundan, bir süreç belleğe her eriştiğinde tüm veri yapısını analiz edemeyiz.

Neyse ki işlemcimiz, sanal ve fiziksel adresler arasındaki eşlemeyi önbelleğe alan bir TLB'ye sahiptir. Bu, ilk erişim denemesinde sayfa tablosunu ayrıştırmamız gerekmesine rağmen, sayfaya yapılan sonraki tüm erişimlerin TLB'de yönetilebileceği ve hızlı çalışmaya olanak tanıyacağı anlamına gelir.

Fiziksel bir cihaz olarak uygulandığı için (ki bu da ilk etapta hızlı olmasını sağlar) kapasitesi sınırlıdır. Dolayısıyla, daha fazla sayfaya erişmek istiyorsanız TLB bunların tümü için eşlemeleri saklayamayacak ve programınızın çok daha yavaş çalışmasına neden olacaktır.

Büyük sayfalar kurtarmaya geliyor

Peki TLB taşmasını önlemek için ne yapabiliriz? (Programın hala aynı miktarda belleğe ihtiyacı olduğunu varsayıyoruz).

İşte Hugepages'in devreye girdiği yer burası. Yalnızca bir TLB girişi gerektiren 4096 bayt yerine, bir TLB girişi artık 2 megabayta kadar devasa bir alanı işaret edebilir. TLB'nin 512 girişi olduğunu varsayalım, burada Hugepages olmadan eşleştirebiliriz:

4096 b⋅512=2 MB

O halde onlarla nasıl karşılaştırabiliriz:

2 MB⋅512=1 GB

Hugepages'in harika olmasının nedeni budur. Çok fazla çaba harcamadan üretkenliği artırabilirler. Ancak burada önemli uyarılar var.

Büyük sayfalar sahtekarlığı

Çekirdek, her bir bellek sayfasının ne sıklıkta kullanıldığını otomatik olarak izler. Yeterli fiziksel bellek (RAM) yoksa, çekirdek, daha önemli sayfalar için bir miktar RAM boşaltmak amacıyla daha az önemli (daha az kullanılan) sayfaları sabit diske taşıyacaktır.
Prensip olarak aynı şey Hugepages için de geçerlidir. Ancak çekirdek tek tek baytları değil, yalnızca sayfaların tamamını değiştirebilir.

Diyelim ki şöyle bir programımız var:

char* mymemory = malloc(2*1024*1024); // Возьмем это за одну Hugepage!
// Заполним mymemory какими-либо данными
// Сделаем много других вещей,
// которые приведут к подмене страницы mymemory
// ...
// Запросим доступ только к первому байту
putchar(mymemory[0]); 

Bu durumda, çekirdeğin yalnızca sizin bir bayt okuyabilmeniz için sabit sürücüden/SSD'den 2 megabayt kadar bilgiyi değiştirmesi (okuması) gerekecektir. Normal sayfalara gelince, sabit sürücüden/SSD'den yalnızca 4096 baytın okunması gerekir.

Bu nedenle, eğer büyük sayfa geçersiz kılınırsa, sayfanın tamamına erişmeniz gerekiyorsa okunması daha hızlı olur. Bu, belleğin farklı bölümlerine rastgele erişmeye çalışıyorsanız ve yalnızca birkaç kilobayt okuyorsanız, normal sayfaları kullanmanız ve başka hiçbir şey için endişelenmemeniz gerektiği anlamına gelir.

Öte yandan, belleğin büyük bir kısmına ardışık olarak erişmeniz gerekiyorsa, büyük sayfalar performansınızı artıracaktır. Ancak bunu kendiniz test etmeniz (soyut bir yazılımla değil) ve neyin daha hızlı çalıştığını görmeniz gerekir.

Bellekteki tahsis

C yazarsanız, yığından isteğe bağlı olarak küçük (veya neredeyse isteğe bağlı olarak büyük) miktarlarda bellek isteyebileceğinizi bilirsiniz. malloc(). Diyelim ki 30 bayt belleğe ihtiyacınız var:

char* mymemory = malloc(30);

Bir programcıya, işletim sisteminden 30 baytlık bellek "talep ediyor" ve bazı sanal belleğe bir işaretçi gönderiyormuşsunuz gibi görünebilir. Ama aslında malloc () sadece fonksiyonun içinden çağıran bir C fonksiyonudur brk ve sbrk işletim sisteminden bellek istemek veya boşaltmak için.

Ancak her ayırma için giderek daha fazla bellek istemek verimsizdir; büyük olasılıkla bazı bellek bölümleri zaten serbest bırakılmıştır (free())ve onu yeniden kullanabiliriz. malloc() boşalan belleğin yeniden kullanılması için oldukça karmaşık algoritmalar uygular.

Aynı zamanda sizin için her şey fark edilmeden gerçekleşir, peki bu sizi neden endişelendirsin? Ama meydan okuma nedeniyle free() bu demek değil bellek mutlaka derhal işletim sistemine iade edilir.

Hafıza parçalanması diye bir şey var. Aşırı durumlarda, yalnızca birkaç baytın kullanıldığı ve aradaki her şeyin serbest bırakıldığı yığın bölümleri vardır (free()).

Bellek parçalanmasının inanılmaz derecede karmaşık bir konu olduğunu ve programda yapılan küçük değişikliklerin bile önemli bir etkiye sahip olabileceğini lütfen unutmayın. Çoğu durumda, programlar önemli miktarda bellek parçalanmasına neden olmaz, ancak yığının bazı alanlarında parçalanma sorunu varsa büyük sayfaların durumu daha da kötüleştirebileceğini bilmelisiniz.

Büyük sayfaların seçici kullanımı

Bu makaleyi okuduktan sonra, programınızın hangi bölümlerinin büyük sayfalar kullanmanın fayda sağlayacağını ve hangilerinin sağlayamayacağını belirlediniz. Peki büyük sayfalar etkinleştirilmeli mi?

Neyse ki kullanabilirsiniz madvise()büyük sayfalamanın yalnızca faydalı olacağı hafıza alanları için etkinleştirilmesi.

Öncelikle, devasa sayfaların madvise() modunda çalışıp çalışmadığını kontrol edin. talimatlar makalenin başında.

Sonra kullan madvise()çekirdeğe büyük sayfaların tam olarak nerede kullanılacağını söylemek için.

#include <sys/mman.h>
// Аллоцируйте большое количество памяти, которую будете использовать
size_t size = 256*1024*1024;
char* mymemory = malloc(size);
// Просто включите hugepages…
madvise(mymemory, size, MADV_HUGEPAGE);
// … и задайте следующее
madvise(mymemory, size, MADV_HUGEPAGE | MADV_SEQUENTIAL)

Bu yöntemin, çekirdeğe belleğin nasıl yönetileceği konusunda basit bir tavsiye olduğunu unutmayın. Bu, çekirdeğin belirli bir bellek için otomatik olarak büyük sayfaları kullanacağı anlamına gelmez.

Belgelere bakın (manpage)madviseBellek yönetimi hakkında daha fazla bilgi edinmek ve madvise(), bu konunun inanılmaz derecede dik bir öğrenme eğrisi var. Bu nedenle, bu konuda gerçekten iyi olmayı düşünüyorsanız, herhangi bir olumlu sonuç beklemeden önce birkaç hafta okumaya ve test etmeye hazırlanın.

Ne okumalı?

Bir sorunuz mu var? Yorumlara yazın!

Kaynak: habr.com

Yorum ekle