GNU/Linux >> Linux の 問題 >  >> Linux

1GB ページを使用するとパフォーマンスが低下する

Intel は親切にもこの問題に回答してくれました。以下の回答をご覧ください。

この問題は、物理ページが実際にコミットされる方法が原因です。 1GB ページの場合、メモリは連続しています。したがって、1GB ページ内の任意の 1 バイトに書き込むとすぐに、1GB ページ全体が割り当てられます。ただし、4KB のページでは、4KB の各ページに初めてアクセスしたときに、物理ページが割り当てられます。

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;
   }
}

最も内側のループでは、インデックスは 512KB のストライドで変化します。したがって、連続した参照は 512KB のオフセットでマップされます。通常、キャッシュには 2048 セット (2^11) があります。したがって、ビット 6:16 がセットを選択します。しかし、512KB のオフセットでストライドすると、ビット 6:16 は同じになり、最終的に同じセットが選択され、空間的局所性が失われます。

クロックを開始して時間を計る前に、以下のように (スモール ページ テストで) 1GB バッファー全体を順次初期化することをお勧めします

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

基本的に、問題はセットの競合にあり、非常に大きな一定のオフセットが原因で、小さなページと比較して巨大なページの場合にキャッシュ ミスが発生します。一定のオフセットを使用する場合、テストは実際にはランダムではありません .


答えではありませんが、この厄介な問題の詳細を提供します。

パフォーマンス カウンターは、ほぼ同じ数の命令を示しますが、ヒュージ ページが使用された場合に消費されるサイクル数は約 2 倍です。

  • 4KiB ページの IPC 0.29、
  • 1 GiB ページの IPC 0.10.

これらの IPC 数値は、コードがメモリ アクセスでボトルネックになっていることを示しています (Skylake の CPU バウンド IPC は 3 以上です)。ヒュージ ページのボトルネックが難しくなります。

MAP_POPULATE | MAP_LOCKED | MAP_FIXED を使用するようにベンチマークを変更しました 固定アドレス 0x600000000000 付き どちらの場合も、ページ フォールトとランダム マッピング アドレスに関連する時間変動を排除します。私の Skylake システムでは、2MiB と 1GiB は 4kiB ページよりも 2 倍以上遅くなります。

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

Intel i9-9900KS (NUMA ではない)、4 つのスロットすべてに 4x8GiB 4GHz CL17 RAM、performance を搭載した Ubuntu 18.04.5 LTS で実行 CPU周波数スケーリングなしのガバナー、サーマルスロットリングなしの最大の液体冷却ファン、プリエンプションなしのFIFO 40優先度、CPU移行なしの1つの特定のCPUコア、複数の実行。結果は clang++-8.0.0 と同様です コンパイラ.

ページ フレームごとのストア バッファなど、ハードウェアに怪しいものがあり、4KiB ページでは単位時間あたり最大 2 倍のストアが可能です。

AMD Ryzen 3 CPU の結果を見るのは興味深いでしょう。

AMD Ryzen 3 5950X では、巨大なページのバージョンは最大 10% 遅くなります:

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. IPブラックリストとしてUFWを使用する

  2. ハイパフォーマンスコンピューティングでChrootを使用する場合の欠点は?

  3. Gitオートコンプリート?

  1. HTMLページでのPHPの使用

  2. LinuxでのNFSパフォーマンスの問題をトラブルシューティングするためのnfsstatおよびnfsiostatの使用

  3. iostat を使用して Linux でシステム パフォーマンスを監視する (例を含む)

  1. キャッシュソリューションXCacheを使用してWebサイトのパフォーマンスを高速化するにはどうすればよいですか?

  2. パフォーマンスと安定性のためのApache2Buddyスクリプトの使用

  3. WindowsPerformanceAnalyzerを使用したパフォーマンスの問題のトラブルシューティング