第6章 CPU
本章では Red Hat Enterprise Linux 7 でアプリケーションのパフォーマンスに影響を与える CPU ハードウェアおよび設定オプションについて簡単に説明します。「留意事項」 ではパフォーマンスに影響を与える CPU 関連の要因について説明します。「パフォーマンスの問題の監視と診断」 では CPU ハードウェアや設定内容に関連するパフォーマンスの問題を分析する Red Hat Enterprise Linux 7 ツールについて説明しています。「推奨設定」 では Red Hat Enterprise Linux 7 で CPU に関するパフォーマンスの問題を解決する際に利用できるツールやストラテジーについて説明しています。
6.1. 留意事項
このセクションを読んで、システムとアプリケーションのパフォーマンスが次の要因によってどのように影響を受けるかを理解してください。
- プロセッサーがどのように相互に、およびメモリーなどの関連リソースに接続されているか。
- プロセッサーによる実行用スレッドのスケジュール方式
- Red Hat Enterprise Linux 7 でのプロセッサーによる割り込み処理の方法
6.1.1. システムのトポロジー
最近のシステムの多くはプロセッサーを複数搭載しているため、central processing unit (CPU ー 中央処理装置) という考えが誤解を招く恐れがあります。このような複数のプロセッサー同士がどのように接続されているか、また他のリソースとはどのように接続されているか (システムの トポロジー) が、システムやアプリケーションのパフォーマンスおよびシステムチューニング時の留意事項に大きな影響を及ぼす可能性があります。
最近のコンピューティングで使用されているトポロジーには主に 2 種類のタイプがあります。
- SMP (Symmetric Multi-Processor) トポロジー
- SMP トポロジーにより、すべてのプロセッサーが同時にメモリーにアクセスできるようになります。ただし、共有および同等のメモリーアクセスは、本質的にすべての CPU からのメモリーアクセスをシリアライズするため、SMP システムのスケーリング制約が一般的に許容できないものとして表示されます。このため、最近のサーバーシステムはすべて NUMA マシンです。
- NUMA (Non-Uniform Memory Access) の固定 (ピニング)
- NUMA トポロジーは、SMP トポロジーよりも最近開発されました。NUMA システムでは、複数のプロセッサーが 1 つのソケット上で物理的にグループ化されます。各ソケットにはメモリー専用の領域があり、メモリーへのローカルアクセスがある複数のプロセッサーをまとめてひとつのノードと呼んでいます。同じノードのプロセッサーはそのノードのメモリーバンクへは高速でアクセスでき、別のノードのメモリーバンクへのアクセスは低速になります。したがってローカルメモリー以外へアクセスする場合にはパフォーマンスが低下します。この点を考慮するとパフォーマンス重視のアプリケーションは NUMA トポロジーの場合アプリケーションを実行しているプロセッサーと同じノードにあるメモリーにアクセスさせるようにして、できるだけリモートのメモリーへのアクセスは避けるようにします。NUMA トポロジーのシステムでアプリケーションのパフォーマンスを調整する場合、アプリケーションが実行される場所そして実行ポイントに最も近いメモリーバンクはどれになるのかを考慮しておくことが重要となります。NUMA トポロジーのシステムでは、
/sys
ファイルシステムには、プロセッサー、メモリー、および周辺機器の接続方法に関する情報が含まれます。/sys/devices/system/cpu
ディレクトリーには、システム内のプロセッサーが互いにどのように接続されているかに関する詳細が含まれます。/sys/devices/system/node
ディレクトリーには、システム内の NUMA ノードに関する情報と、それらのノード間の相対距離に関する情報が含まれます。
6.1.1.1. システムのトポロジーの判断
トポロジーを理解するのに役立つコマンドが数種類あります。numactl --hardware コマンドを使用すると、システムのトポロジーの概要を説明します。
$ numactl --hardware available: 4 nodes (0-3) node 0 cpus: 0 4 8 12 16 20 24 28 32 36 node 0 size: 65415 MB node 0 free: 43971 MB node 1 cpus: 2 6 10 14 18 22 26 30 34 38 node 1 size: 65536 MB node 1 free: 44321 MB node 2 cpus: 1 5 9 13 17 21 25 29 33 37 node 2 size: 65536 MB node 2 free: 44304 MB node 3 cpus: 3 7 11 15 19 23 27 31 35 39 node 3 size: 65536 MB node 3 free: 44329 MB node distances: node 0 1 2 3 0: 10 21 21 21 1: 21 10 21 21 2: 21 21 10 21 3: 21 21 21 10
lscpu コマンドは util-linux パッケージで提供されます。CPU 数、スレッド数、コア数、ソケット数、NUMA ノード数など、CPU アーキテクチャーに関する情報を収集します。
$ lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 40 On-line CPU(s) list: 0-39 Thread(s) per core: 1 Core(s) per socket: 10 Socket(s): 4 NUMA node(s): 4 Vendor ID: GenuineIntel CPU family: 6 Model: 47 Model name: Intel(R) Xeon(R) CPU E7- 4870 @ 2.40GHz Stepping: 2 CPU MHz: 2394.204 BogoMIPS: 4787.85 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 30720K NUMA node0 CPU(s): 0,4,8,12,16,20,24,28,32,36 NUMA node1 CPU(s): 2,6,10,14,18,22,26,30,34,38 NUMA node2 CPU(s): 1,5,9,13,17,21,25,29,33,37 NUMA node3 CPU(s): 3,7,11,15,19,23,27,31,35,39
lstopo コマンドは hwloc パッケージで提供され、システムをグラフィカルに表示します。lstopo-no-graphics コマンドは、詳細なテキスト出力を提供します。

lstopo コマンドの出力
6.1.2. スケジューリング
Red Hat Enterprise Linux ではプロセス実行の最小単位を スレッド と呼んでいます。システムスケジューラーは、スレッドを実行するプロセッサーと、スレッドの実行期間を決定します。ただし、システムにとっての最優先事項はシステムを無駄なく稼動させることであるため、アプリケーションのパフォーマンスという観点からは最適なスケジューリングではないかもしれません。
たとえば、NUMA システムで ノード B のプロセッサーが利用可能になったときアプリケーションはノード A で実行中だったと仮定します。ノード B のプロセッサーを稼働状態に保つため、スケジューラーはアプリケーションのスレッドの 1 つをノード B に移動します。しかし、このアプリケーションスレッドは引き続きノード A のメモリーへのアクセスを必要とします。移動したスレッドはノード Β で実行され、ノード A のメモリーはこのスレッドのローカルメモリーではなくなるため、アクセスに時間がかかるようになります。ノード A のプロセッサーが利用できるようになるまで待機する時間や、ローカルメモリーにアクセスして以前のノードでスレッドを実行する時間よりも、このスレッドがノード B で実行を完了する時間の方が長くなる可能性があります。
パフォーマンス重視のアプリケーションには、多くの場合、スレッドが実行される場所を決定する手段や管理者の恩恵を受けることができます。パフォーマンス重視のアプリケーションのニーズに合うよう適切にスレッドのスケジュールを行う方法については、「スケジューリングポリシーの調整」 を参照してください。
6.1.2.1. カーネルティック
Red Hat Enterprise Linux の旧バージョンでは Linux カーネルは完了すべき作業確認のため各 CPU に定期的な割り込みを行っていました。その結果を使用してプロセスのスケジューリングや負荷分散に関する決定を下していました。この定期的な割り込みをカーネル ティック と呼んでいました。
コアで行う作業があったかどうかに関わらずティックは発生していました。つまり、アイドル状態のコアであっても割り込み応答を定期的に強制されるため電力消費が高くなっていました (最大 1000 倍/秒)。このためシステムは最近の x86 プロセッサーに搭載されているディープスリープ状態を効率的に利用することができませんでした。
Red Hat Enterprise Linux 6 および 7 ではカーネルはデフォルトでは電力消費が低いアイドル状態の CPU には割り込みをしないようになります。ティックレスカーネルと呼ばれる動作です。実行しているタスクが少ない場合、定期的な割り込みはオンデマンドの割り込みに代わっているためアイドル状態の CPU はその状態またはそれ以下の電力消費状態により長く維持され節電となります。
Red Hat Enterprise Linux 7 では動的なティックレスオプション (
nohz_full
) が用意されユーザー領域タスクによるカーネルの干渉を低減することで決定論がさらに向上されています。このオプションは、nohz_full
カーネルパラメーターを使用して、指定したコアで有効にできます。コアでオプションを有効にすると時間管理に関するアクティビティーはすべて待ち時間に制約のないコアに移動されます。ユーザー領域のタスクがカーネルタイマーティック関連の待ち時間にマイクロ秒単位で制約がある高性能な計算やリアルタイムの計算を必要とする作業に便利です。
Red Hat Enterprise Linux 7 で動的なティックレス動作を有効にする方法については、「カーネルティックタイムの設定」 を参照してください。
6.1.3. IRQ (Interrupt Request ー 割り込み要求) の処理
割り込み要求または IRQ は、ハードウェアの一部からプロセッサーに直ちに送信されるシグナルです。システム内の各デバイスには固有な割り込みを送信できるようひとつまたは複数の IRQ 番号が割り当てられます。割り込みを有効にすると割り込み要求を受け取るプロセッサーは割り込み要求に応答するため現在のアプリケーションスレッドの実行を直ちに中断します。
通常の動作を停止するため、割り込み率が高ければシステムのパフォーマンスが著しく低下する可能性があります。割り込みの親和性を設定する、または優先度の低い複数の割り込みを 1 つのバッチ (複数の割り込みをまとめる) にして送信することで割り込みにかかる時間を低減することが可能です。
割り込み要求の調整については、「AMD64 および Intel 64 での割り込み親和性の設定」 または 「Tuna を使用した CPU、スレッド、割り込みの親和性の設定」 を参照してください。ネットワーク割り込みの詳細については、9章ネットワーク を参照してください。