GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Die Verwendung von 1-GB-Seiten beeinträchtigt die Leistung

Intel war so freundlich, auf dieses Problem zu antworten. Siehe ihre Antwort unten.

Dieses Problem ist darauf zurückzuführen, wie physische Seiten tatsächlich festgeschrieben werden. Bei 1-GB-Seiten ist der Speicher zusammenhängend. Sobald Sie also auf ein beliebiges Byte innerhalb der 1-GB-Seite schreiben, wird die gesamte 1-GB-Seite zugewiesen. Bei 4-KB-Seiten werden die physischen Seiten jedoch zugewiesen, sobald Sie die 4-KB-Seiten zum ersten Mal berühren.

for (uint64_t i = 0; i < size / MESSINESS_LEVEL / sizeof(*ptr); i++) {
   for (uint64_t j = 0; j < MESSINESS_LEVEL; j++) {
       index = i + j * size / MESSINESS_LEVEL / sizeof(*ptr);
           ptr[index] = index * 5;
   }
}

In der innersten Schleife ändert sich der Index mit einer Schrittweite von 512 KB. Aufeinanderfolgende Referenzen werden also bei 512-KB-Offsets abgebildet. Typischerweise haben Caches 2048 Sets (das sind 2^11). Also, Bits 6:16 wählen die Sets aus. Aber wenn Sie bei 512 KB-Offsets schreiten, wären die Bits 6:16 dieselben, was dazu führen würde, dass Sie denselben Satz auswählen und die räumliche Lokalität verlieren.

Wir empfehlen, den gesamten 1-GB-Puffer sequenziell (im kleinen Seitentest) wie unten zu initialisieren, bevor Sie die Uhr starten, um ihn zu timen

for (uint64_t i = 0; i < size / sizeof(*ptr); i++)
    ptr[i] = i * 5;

Grundsätzlich besteht das Problem in Set-Konflikten, die bei großen Seiten im Vergleich zu kleinen Seiten aufgrund sehr großer konstanter Offsets zu Cache-Fehlern führen. Wenn Sie konstante Offsets verwenden, ist der Test wirklich nicht zufällig .


Keine Antwort, aber um mehr Details zu diesem verwirrenden Problem bereitzustellen.

Leistungszähler zeigen ungefähr die gleiche Anzahl von Anweisungen, aber ungefähr die doppelte Anzahl von Zyklen, die verbraucht werden, wenn riesige Seiten verwendet werden:

  • 4KiB Seiten IPC 0.29,
  • 1-GiB-Seiten IPC 0.10.

Diese IPC-Zahlen besagen, dass der Code beim Speicherzugriff einen Engpass aufweist (CPU-gebundener IPC auf Skylake ist 3 und höher). Riesige Seiten Engpass härter.

Ich habe Ihren Benchmark so modifiziert, dass er MAP_POPULATE | MAP_LOCKED | MAP_FIXED verwendet mit fester Adresse 0x600000000000 für beide Fälle, um Zeitvariationen zu eliminieren, die mit Seitenfehlern und zufälligen Zuordnungsadressen verbunden sind. Auf meinem Skylake-System sind 2 MiB und 1 GiB mehr als zweimal langsamer als 4 KB-Seiten.

Kompiliert mit g++-8.4.0 -std=gnu++14 -pthread -m{arch,tune}=skylake -O3 -DNDEBUG :

[[email protected]:~/src/test] $ sudo hugeadm --pool-pages-min 2MB:64 --pool-pages-max 2MB:64
[[email protected]:~/src/test] $ sudo hugeadm --pool-pages-min 1GB:1 --pool-pages-max 1GB:1
[[email protected]:~/src/test] $ for s in small huge; do sudo chrt -f 40 taskset -c 7 perf stat -dd ./release/gcc/test $s random; done
Duration: 2156150

 Performance counter stats for './release/gcc/test small random':

       2291.190394      task-clock (msec)         #    1.000 CPUs utilized          
                 1      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
                53      page-faults               #    0.023 K/sec                  
    11,448,252,551      cycles                    #    4.997 GHz                      (30.83%)
     3,268,573,978      instructions              #    0.29  insn per cycle           (38.55%)
       430,248,155      branches                  #  187.784 M/sec                    (38.55%)
           758,917      branch-misses             #    0.18% of all branches          (38.55%)
       224,593,751      L1-dcache-loads           #   98.025 M/sec                    (38.55%)
       561,979,341      L1-dcache-load-misses     #  250.22% of all L1-dcache hits    (38.44%)
       271,067,656      LLC-loads                 #  118.309 M/sec                    (30.73%)
           668,118      LLC-load-misses           #    0.25% of all LL-cache hits     (30.73%)
   <not supported>      L1-icache-loads                                             
           220,251      L1-icache-load-misses                                         (30.73%)
       286,864,314      dTLB-loads                #  125.203 M/sec                    (30.73%)
             6,314      dTLB-load-misses          #    0.00% of all dTLB cache hits   (30.73%)
                29      iTLB-loads                #    0.013 K/sec                    (30.73%)
             6,366      iTLB-load-misses          # 21951.72% of all iTLB cache hits  (30.73%)

       2.291300162 seconds time elapsed

Duration: 4349681

 Performance counter stats for './release/gcc/test huge random':

       4385.282466      task-clock (msec)         #    1.000 CPUs utilized          
                 1      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
                53      page-faults               #    0.012 K/sec                  
    21,911,541,450      cycles                    #    4.997 GHz                      (30.70%)
     2,175,972,910      instructions              #    0.10  insn per cycle           (38.45%)
       274,356,392      branches                  #   62.563 M/sec                    (38.54%)
           560,941      branch-misses             #    0.20% of all branches          (38.63%)
         7,966,853      L1-dcache-loads           #    1.817 M/sec                    (38.70%)
       292,131,592      L1-dcache-load-misses     # 3666.84% of all L1-dcache hits    (38.65%)
            27,531      LLC-loads                 #    0.006 M/sec                    (30.81%)
            12,413      LLC-load-misses           #   45.09% of all LL-cache hits     (30.72%)
   <not supported>      L1-icache-loads                                             
           353,438      L1-icache-load-misses                                         (30.65%)
         7,252,590      dTLB-loads                #    1.654 M/sec                    (30.65%)
               440      dTLB-load-misses          #    0.01% of all dTLB cache hits   (30.65%)
               274      iTLB-loads                #    0.062 K/sec                    (30.65%)
             9,577      iTLB-load-misses          # 3495.26% of all iTLB cache hits   (30.65%)

       4.385392278 seconds time elapsed

Läuft auf Ubuntu 18.04.5 LTS mit Intel i9-9900KS (das nicht NUMA ist), 4x8GiB 4GHz CL17 RAM in allen 4 Slots, mit performance Governor für keine CPU-Frequenzskalierung, Flüssigkeitskühlungslüfter auf Maximum für keine thermische Drosselung, FIFO 40-Priorität für keine Vorrangigkeit, auf einem bestimmten CPU-Kern für keine CPU-Migration, mehrere Läufe. Die Ergebnisse sind ähnlich mit clang++-8.0.0 Compiler.

Es fühlt sich an, als wäre etwas in der Hardware faul, wie ein Speicherpuffer pro Seitenrahmen, sodass 4-KiB-Seiten ~ 2x mehr Speicher pro Zeiteinheit ermöglichen.

Wäre interessant, Ergebnisse für AMD Ryzen 3 CPUs zu sehen.

Auf AMD Ryzen 3 5950X ist die Huge-Pages-Version nur bis zu 10 % langsamer:

Duration: 1578723

 Performance counter stats for './release/gcc/test small random':

          1,726.89 msec task-clock                #    1.000 CPUs utilized          
                 0      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
             1,947      page-faults               #    0.001 M/sec                  
     8,189,576,204      cycles                    #    4.742 GHz                      (33.02%)
         3,174,036      stalled-cycles-frontend   #    0.04% frontend cycles idle     (33.14%)
            95,950      stalled-cycles-backend    #    0.00% backend cycles idle      (33.25%)
     3,301,760,473      instructions              #    0.40  insn per cycle         
                                                  #    0.00  stalled cycles per insn  (33.37%)
       480,276,481      branches                  #  278.116 M/sec                    (33.49%)
           864,075      branch-misses             #    0.18% of all branches          (33.59%)
       709,483,403      L1-dcache-loads           #  410.844 M/sec                    (33.59%)
     1,608,181,551      L1-dcache-load-misses     #  226.67% of all L1-dcache accesses  (33.59%)
   <not supported>      LLC-loads                                                   
   <not supported>      LLC-load-misses                                             
        78,963,441      L1-icache-loads           #   45.726 M/sec                    (33.59%)
            46,639      L1-icache-load-misses     #    0.06% of all L1-icache accesses  (33.51%)
       301,463,437      dTLB-loads                #  174.570 M/sec                    (33.39%)
       301,698,272      dTLB-load-misses          #  100.08% of all dTLB cache accesses  (33.28%)
                54      iTLB-loads                #    0.031 K/sec                    (33.16%)
             2,774      iTLB-load-misses          # 5137.04% of all iTLB cache accesses  (33.05%)
       243,732,886      L1-dcache-prefetches      #  141.140 M/sec                    (33.01%)
   <not supported>      L1-dcache-prefetch-misses                                   

       1.727052901 seconds time elapsed

       1.579089000 seconds user
       0.147914000 seconds sys

Duration: 1628512

 Performance counter stats for './release/gcc/test huge random':

          1,680.06 msec task-clock                #    1.000 CPUs utilized          
                 1      context-switches          #    0.001 K/sec                  
                 1      cpu-migrations            #    0.001 K/sec                  
             1,947      page-faults               #    0.001 M/sec                  
     8,037,708,678      cycles                    #    4.784 GHz                      (33.34%)
         4,684,831      stalled-cycles-frontend   #    0.06% frontend cycles idle     (33.34%)
         2,445,415      stalled-cycles-backend    #    0.03% backend cycles idle      (33.34%)
     2,217,699,442      instructions              #    0.28  insn per cycle         
                                                  #    0.00  stalled cycles per insn  (33.34%)
       281,522,918      branches                  #  167.567 M/sec                    (33.34%)
           549,427      branch-misses             #    0.20% of all branches          (33.33%)
       312,930,677      L1-dcache-loads           #  186.261 M/sec                    (33.33%)
     1,614,505,314      L1-dcache-load-misses     #  515.93% of all L1-dcache accesses  (33.33%)
   <not supported>      LLC-loads                                                   
   <not supported>      LLC-load-misses                                             
           888,872      L1-icache-loads           #    0.529 M/sec                    (33.33%)
            13,140      L1-icache-load-misses     #    1.48% of all L1-icache accesses  (33.33%)
             9,168      dTLB-loads                #    0.005 M/sec                    (33.33%)
               870      dTLB-load-misses          #    9.49% of all dTLB cache accesses  (33.33%)
             1,173      iTLB-loads                #    0.698 K/sec                    (33.33%)
             1,914      iTLB-load-misses          #  163.17% of all iTLB cache accesses  (33.33%)
       253,307,275      L1-dcache-prefetches      #  150.772 M/sec                    (33.33%)
   <not supported>      L1-dcache-prefetch-misses                                   

       1.680230802 seconds time elapsed

       1.628170000 seconds user
       0.052005000 seconds sys

Linux
  1. Verwendung von PHP in HTML-Seiten

  2. Git-Autovervollständigung?

  3. Wie kann die Website-Performance mit der Caching-Lösung XCache beschleunigt werden?

  4. Was ist eine Möglichkeit, Manpages in vim zu lesen, ohne temporäre Dateien zu verwenden?

  5. Maximierung der rsync-Leistung und des Durchsatzes – direkt verbundene Gigabit-Server

So überwachen Sie die Linux-Leistung mit dem Systat-Tool

Verwenden von Runit auf Devuan

So überwachen Sie die Apache-Leistung mit mod_status in Ubuntu

So überwachen Sie die Ubuntu-Leistung mit Netdata

Verwenden von vmstat zum Beheben von Leistungsproblemen unter Linux

Leistungssteigerung durch Verwendung eines zusätzlichen statischen Dateiservers