スワップオフがなぜそんなに遅いのですか?

スワップオフがなぜそんなに遅いのですか?

たぶん、偶然に14GBのRAMを交換することになりました。犯人を殺してしまったらまた余裕メモリがたくさんできてそうできると思いました。重要なデータのインポート再び。そこで32GBのうち5GBと14GBのスワップ空間を使って実行しましたがswapoff -a…4時間後に作業の半分程度が完了しました。

これは1MB /秒未満を意味しますが、200MB /秒は簡単にコピーできます。私のスワップ領域は暗号化されていますが、すべての通常のパーティションも同じです。エスニーかなりのCPU負荷は発生しません(そしてスワップスペースを埋めるのに数分しかかかりません)。最適化する特別な理由はありませんが、swapoffどのようにそれが遅くなるのか疑問に思います。


データを追加するだけです。 4つのハードドライブのそれぞれに32GBのメインメモリと32GBのスワップスペースがあります(確かに冗長ですが、誰が気にしますか?)。フルスワップスペースは5分以内に復号化および読み取ることができます。

time -p sudo sh -c 'for i in /dev/mapper/cryptswap?; do md5sum $i & done; wait'
014a2b7ef300e11094134785e1d882af  /dev/mapper/cryptswap1
a6d8ef09203c1d8d459109ff93b6627c  /dev/mapper/cryptswap4
05aff81f8d276ddf07cf26619726a405  /dev/mapper/cryptswap3
e7f606449327b9a016e88d46049c0c9a  /dev/mapper/cryptswap2
real 264.27

パーティションの一部を読むことは、パーティション全体を読み取るよりも遅くはありません。しかし、約1/10を読むと時間が約100倍長くなります。

私はswapoff両方のプロセスでディスク(LEDで「測定」)と同様に、CPUがほとんどアイドル状態(コアの10%程度)であることを確認しました。私もスワップスペースが順番に閉じているのを見ました。

答え1

まず、ハードドライブで何が期待できるかを見てみましょう。ハードドライブは200MB / sに達することができます。一つずつ。ナビゲーション時間を考慮すると、次のようになります。たくさんゆっくり。任意の例として、Seagateの最新の3TBディスク仕様を見てください。ST3000DM001:

  • 最大持続データレート: 210MB/s

  • 平均ナビゲーションを読む:<8.5ms

  • セクタあたりのバイト:4,096

検索する必要がなく、スワップがディスクの端に近い場合は、最大速度 =210MB/秒

ただし、スワップデータが完全に分散している場合は、最悪の場合は読み取ったすべてのセクタを検索する必要があります。これは、8.5ミリ秒ごとに4KBしか読み取ることができないことを意味します。つまり、4KB/0.0085=470KB/秒

だから今はそうではありません。信じられない実際にハードドライブの速度で実行されています。


つまり、swapoff遅すぎるとページを順番に読む必要があるのは愚かなようです。特に、ページが非常に迅速に(順番に)作成されている場合はさらにそうです。しかし、おそらくカーネルがどのように機能するのでしょうか。 Ubuntuのバグレポート#486666同じ問題について話し合います。

The swap is being removed at speed of 0.5 MB/s, while the
hard drive speed is 60 MB/s;
No other programs are using harddrive a lot, system is not under
high load etc.

Ubuntu 9.10 on quad core.

Swap partition is encrypted.
Top (atop) shows near 100% hard drive usage
  DSK | sdc | busy 88% | read 56 | write 0 | avio 9 ms |
but the device transfer is low (kdesysguard)
  0.4 MiB/s on /dev/sdc reads, and 0 on writes

答えの1つは次のとおりです。

It takes a long time to sort out because it has to rearrange and flush the
memory, as well as go through multiple decrypt cycles, etc. This is quite
normal

このバグレポートは終了し、解決されませんでした。

メルゴーマ​​ンの本Linux仮想メモリマネージャについて「ちょっと昔ながらですが、作業速度が遅いことに同意します。

予想通り、ゾーンの無効化を担当する関数が呼び出されますsys_swapoff()。この機能は主にアップデートに関連していますswap_info_struct。各コールアウトページのページ付けの主な作業は次のとおりですtry_to_unuse()極度に高価です。

2007年以来、Linux-kernelメーリングリストでこのトピックについて「より多くの議論」がありました。交換速度の向上"--たとえ彼らが議論するスピードはあなたが見るよりも少し速いですが。


これはほとんど使用されないため、一般的に見落とされる可能性がある興味深い質問ですswapoff。本当に追跡したい場合は、最初のステップはディスク使用パターンをより詳しく調べることです(おそらく、またはなどのより強力なツールを使用してatop)。過度の検索、小規模I / O操作、継続的な書き換え、データの移動などを確認する必要があります。iostatperfsystemtap

答え2

私のラップトップにも同じ問題があります。ノートブックにはSSDが装備されているため、検索時間は問題になりません。

私が見つけた別の説明。以下は抜粋です

現在機能しているように、swapoffはスワップパーティションからスワップアウトされた各メモリページを見て、それを使用するすべてのプログラムを見つけようとします。すぐに見つからない場合は、実行中のすべてのプログラムのページテーブルを確認してください。最悪の場合は、パーティションで置き換えられたすべてのページのすべてのページテーブルを確認してください。そうですね。同じページテーブルが引き続き確認されます。

したがって、これはカーネルの問題であり、他の問題ではありません。

答え3

はい、このswapoffメカニズムは非常に非効率的です。解決策は簡単です。置き換えられたページではなく、プロセスを繰り返すことです。次のPythonスクリプトを使用してください(私は関係ありません)。

git clone https://github.com/wiedemannc/deswappify-auto
cd ./deswappify-auto
sudo python3 deswappify_auto.py -d -v info

デーモンの動作モードは、しばしばスリープモードに入るデスクトップ/ノートブックコンピュータにのみ適していることに注意してください。私はそれをサーバーシステムからデーモンとして実行しません。しばらく実行し、いくつかのプロセスが処理されたことを報告するのを待ってから、停止して試してください。

swapoff /dev/x

ほとんどのページがスワップとメモリにあるので、やることはswapoffほとんどなく、速度もかなり速くなります(数百MB / sで表示されます)。

以前の歴史的部分

前述のPythonスクリプトはこの回答の残りの部分に基づいており、結果的に私の改善です。この古い答え作家:ジロン。スクリプトがより安全なのでお勧めします最後の防衛線で私の答えの残りの部分を試してみてください。:

perl -we 'for(`ps -e -o pid,args`) { if(m/^ *(\d+) *(.{0,40})/) { $pid=$1; $desc=$2; if(open F, "/proc/$pid/smaps") { while(<F>) { if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ $start_adr=$1; $end_adr=$2; }  elsif(m/^Swap:\s*(\d\d+) *kB/s){ print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" }}}}}' | sort -Vr | head

これは2秒間実行でき、最初の10個のメモリセグメントを一覧表示する以外は実際には何もしません(実際には1行ずつより多くの内容を印刷します。はい、私はする冗談が好きです。コマンドを確認し、リスクを取ってシェルにコピーして貼り付けると、実際に交換から読み込まれます。

...Paste the generated one-liners...
swapoff /your/swap    # much faster now

一行のコードは/procをたくさん読むことを除いて安全です。

手動検査用に準備されたサブコマンドは次のとおりです。安全ではない。各コマンドは、スワップからメモリセグメントを読み取る間にプロセスを一時停止します。したがって、中断されたプロセスを許可しないことは安全ではありません。私が見ている転送速度は毎分約1GBです。 (前述のPythonスクリプトはこの欠陥を取り除きます)。

別のリスクは、システムに過度のメモリ圧力を加えることです。free -m

それは何をしますか?

for(`ps -e -o pid,args`) {

  if(m/^ *(\d+) *(.{0,40})/) { 
    $pid=$1; 
    $desc=$2; 

    if(open F, "/proc/$pid/smaps") { 

      while(<F>) { 

        if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ 
          $start_adr=$1; 
          $end_adr=$2; 
        } elsif( m/^Swap:\s*(\d\d+) *kB/s ){
          print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" 
        }
      }
    }
  }
}

このPerlスクリプトの出力は、置き換えられたページをメモリにロードする一連のgdbコマンドです。dump memory (range)

出力はサイズから始まるため、| sort -Vr | headサイズ(SSIZE)に基づいて最大10個のセグメントを簡単に取得できます。バージョン番号を表すのは-Vソートには適していますが、私の目的には適しています。数値の並べ替えを行う方法がわかりません。

答え4

スワップ中に使用中のスワップスロットが検出されると、カーネルは最初にそのページをスワップします。その後、unuse_process()関数は、置き換えられたページに対応するすべてのページテーブルエントリを見つけ、ページテーブルに必要な更新を実行しようとします。検索は徹底的で時間がかかります。システム全体のすべてのメモリ記述子にアクセスし、ページテーブルエントリを1つずつ確認します。

「Linuxカーネル第3版について」の724ページを参照してください。

関連情報