Domanda

CPU x86 moderni hanno la capacità di supportare formati di pagina più grandi della legacy 4K (vale a dire 2 MB o 4 MB), e ci sono strutture OS ( Linux , di Windows ) per accedere a questa funzionalità.

Il collegamento Microsoft sopra gli stati grandi pagine "aumentare l'efficienza del buffer di traduzione, che può aumentare le prestazioni per la memoria si accede di frequente". Che non è molto utile nel predire se grandi pagine migliorerà una determinata situazione. Mi interessa in calcestruzzo, preferibilmente quantificati, esempi di dove si muove un po 'di logica del programma (o un intero applicazione) per utilizzare le pagine enormi ha portato a qualche miglioramento delle prestazioni. Chiunque ha ottenuto tutte le storie di successo?

C'è un caso particolare che conosco me : usando enorme pagine possono drammaticamente ridurre il tempo necessario per fork di un grande processo (presumibilmente come il numero di record TLB necessitano di copia viene ridotta di un fattore dell'ordine di 1000). Mi interessa se enormi pagine possono anche essere un vantaggio in scenari meno esotici.

È stato utile?

Soluzione 2

Ho cercato di escogitare un codice che avrebbe massimizzare botte del TLB con 4K pagine al fine di esaminare i guadagni possibili dalle grandi pagine. La roba di seguito viene eseguito 2,6 volte più veloce (oltre 4K pagine) quando le pagine sono 2MByte sono forniti da malloc di libhugetlbfs (Intel i7, 64bit Debian Lenny); si spera ovvio cosa scoped_timer e random0n fare.

  volatile char force_result;

  const size_t mb=512;
  const size_t stride=4096;
  std::vector<char> src(mb<<20,0xff);
  std::vector<size_t> idx;
  for (size_t i=0;i<src.size();i+=stride) idx.push_back(i);
  random0n r0n(/*seed=*/23);
  std::random_shuffle(idx.begin(),idx.end(),r0n);

  {
    scoped_timer t
      ("TLB thrash random",mb/static_cast<float>(stride),"MegaAccess");
    char hash=0;
    for (size_t i=0;i<idx.size();++i) 
      hash=(hash^src[idx[i]]);
    force_result=hash;
  }

Una versione più semplice "linea retta" con un solo hash=hash^src[i] ha guadagnato solo il 16% dalle grandi pagine, ma (speculazione selvaggia) di Intel fantasia prefetching hardware può aiutare il 4K caso in cui gli accessi sono prevedibili (suppongo che potrei disable prefetching di indagare se questo è vero).

Altri suggerimenti

La più grande differenza di prestazioni verrà quando si sta facendo gli accessi casuali ampiamente distanziati di una grande regione della memoria - dove i mezzi "grandi" molto più grande della gamma che può essere mappato da tutte le piccole voci pagina nel TLB (che in genere hanno livelli multipli di processori moderni).

Per rendere le cose più complesse, il numero di voci TLB per le pagine 4 KB è spesso maggiore del numero di voci per le pagine 2MB, ma questo varia molto da processore. C'è anche un sacco di variazione nel modo in cui molte voci "grande pagina" sono disponibili nel livello 2 TLB.

Ad esempio, su un 10h AMD Opteron Famiglia Revisione D ( "Istanbul") del sistema, i rapporti CPUID:

  • L1 DTLB: pagine 4 KB: 48 voci; pagine 2MB: 48 voci; pagine 1 GB: 48 voci
  • L2 TLB: pagine 4 KB: 512 voci; pagine 2MB: 128 entries; pagine 1 GB: 16 voci

Mentre su un sistema Intel Xeon 56xx ( "Westmere"), i rapporti CPUID:

  • L1 DTLB: pagine 4 KB: 64 voci; pagine 2MB: 32 voci
  • L2 TLB: pagine 4 KB: 512 voci; pagine 2MB: nessuno

Entrambi possono mappare 2 MB (512 * 4kB) utilizzando piccoli pagine prima di livello sofferenza 2 miss TLB, mentre il sistema Westmere può mappare 64MB con le sue 32 voci 2MB TLB e il sistema AMD può mappare 352MB utilizzando le 176 voci 2MB TLB nella sua L1 e L2 TLB. Entrambi i sistemi si ottiene un aumento di velocità significativo utilizzando pagine di grandi dimensioni per gli accessi casuali oltre intervalli di memoria che sono molto più grandi di 2 MB e meno di 64 MB. Il sistema AMD dovrebbe continuare a mostrare buone prestazioni usando pagine di grandi dimensioni per gli intervalli di memoria molto più grandi.

Che cosa si sta cercando di evitare in tutti questi casi è il caso peggiore (nota 1) scenario di attraversare tutti e quattro i livelli del x86_64 traduzione gerarchica degli indirizzi.
Se nessuno dei meccanismi di traduzione degli indirizzi di caching (Nota 2) il lavoro, si richiede:

  • 5 gite a memoria per caricare i dati mappati su una pagina 4kB,
  • 4 viaggi in memoria per caricare i dati mappati su una pagina 2MB, e
  • 3 viaggi a memoria per caricare i dati mappati su una pagina 1 GB.

In ogni caso l'ultimo viaggio nella memoria è quello di ottenere i dati richiesti, mentre gli altri viaggi sono tenuti ad ottenere le varie parti delle informazioni di traduzione pagina. La descrizione migliore che ho visto è nella sezione 5.3 di AMD "AMD64 Architecture Programmer Manuale Volume 2: programmazione di sistema" (pubblicazione 24593) http://support.amd.com/us/Embedded_TechDocs/24593.pdf

Nota 1: I dati sopra riportati non sono realmente il peggiore caso. In esecuzione in una macchina virtuale fa che peggiorare questi numeri. L'esecuzione in un ambiente che fa sì che la memoria che i diversi livelli delle tabelle pagina per ottenere scambiato su disco rende le prestazioni molto di peggio.

Nota 2: Purtroppo, pur sapendo questo livello di dettaglio non è sufficiente, perché tutti i processori moderni hanno cache aggiuntivi per i livelli superiori della gerarchia di traduzione pagina. Per quanto posso dire questi sono molto scarsamente documentati in pubblico.

Ho visto un miglioramento in alcuni scenari HPC / grid - in particolare pacchetti di fisica con molto, molto grandi modelli su macchine con un sacco e un sacco di RAM. Anche il processo in esecuzione il modello era l'unica cosa attiva sulla macchina. Ho il sospetto che, anche se non hanno misurato, che alcune funzioni DB (ad esempio importazioni di massa) trarrebbero vantaggio pure.

Personalmente, penso che se non si dispone di un profilo di accesso capito molto bene profilato / memoria e fa un sacco di grandi dimensioni l'accesso alla memoria, è improbabile che si vedrà alcun miglioramento significativo.

Questa è sempre esoterica, ma le pagine TLB Enormi fare una differenza significativa su architettura Intel Xeon Phi (MIC) quando fare trasferimenti di memoria DMA (da host a Phi via PCIe). Questo link Intel descrive come abilitare enormi pagine . Ho trovato l'aumento delle dimensioni di trasferimento DMA oltre 8 MB con le normali dimensioni della pagina TLB (4K) ha iniziato a prestazioni diminuzione, da circa 3 GB / s per meno di 1 GB / s, una volta la dimensione di trasferimento ha colpito 512 MB.

Dopo aver attivato enormi pagine TLB (2MB), la velocità dei dati ha continuato ad aumentare a più di 5 GB / s per i trasferimenti DMA di 512 MB.

ho un ~ 5% aumento di velocità su server con un sacco di memoria (> = 64 GB) in esecuzione grandi processi. per esempio. per un processo di Java da 16 GB, che è 4M x 4 KB pagine ma solo 4k x 4MB pagine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top