第6章 CPU

本章では Red Hat Enterprise Linux 7 でアプリケーションのパフォーマンスに影響を与える CPU ハードウェアおよび設定オプションについて簡単に説明します。「留意事項」ではパフォーマンスに影響を与える CPU 関連の要因について、「パフォーマンスの問題の監視と診断」では CPU ハードウェアや設定内容に関連するパフォーマンスの問題を分析するツールについて説明しています。「推奨設定」では Red Hat Enterprise Linux 7 で CPU に関するパフォーマンスの問題を解決する際に利用できるツールやストラテジーについて説明しています。

6.1. 留意事項

この最初の項を読むと、以下のような要因がシステムおよびアプリケーションのパフォーマンスに与える影響について理解できます。
  • プロセッサー同士およびメモリーなど関連リソースとの接続形態
  • プロセッサーによる実行用スレッドのスケジュール方式
  • Red Hat Enterprise Linux 7 でのプロセッサーによる割り込み処理の方法

6.1.1. システムのトポロジー

最近のシステムの多くはプロセッサーを複数搭載しているため、central processing unit (CPU ー 中央処理装置) という考えが誤解を招く恐れがあります。このような複数のプロセッサー同士がどのように接続されているか、また他のリソースとはどのように接続されているか (システムの トポロジー) が、システムやアプリケーションのパフォーマンスおよびシステムチューニング時の留意事項に大きな影響を及ぼす可能性があります。
最近のコンピューティングで使用されているトポロジーには主に 2 種類のタイプがあります。
Symmetric Multi-Processor (SMP) トポロジー
SMP トポロジーの場合、すべてのプロセッサーが同じ時間量メモリーにアクセスすることができます。ただし、メモリーアクセスへの平等な共有は本質的に全 CPU からのメモリーアクセスを直列化することになるため、SMP システムでのスケーリングにおける制約が全般的に許容できないレベルと見られるようになってきました。こうした状況のため実際には最近のサーバーシステムではすべて NUMA マシンが使われています。
Non-Uniform Memory Access (NUMA) トポロジー
NUMA トポロジーは SMP トポロジーより後に開発されました。NUMA システムでは複数のプロセッサーがひとつのソケット上で物理的にまとめられています。各ソケットにはメモリー専用の領域があり、メモリーへのローカルアクセスがある複数のプロセッサーをまとめてひとつのノードと呼んでいます。
同じノードのプロセッサーはそのノードのメモリーバンクへは高速でアクセスでき、別のノードのメモリーバンクへのアクセスは低速になります。したがってローカルメモリー以外へアクセスする場合にはパフォーマンスが低下します。
この点を考慮するとパフォーマンス重視のアプリケーションは 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 コマンドを使用するとテキスト形式の出力になります。
Graphical output of the lstopo command on a system with four NUMA nodes
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 番号が割り当てられます。割り込みを有効にすると割り込み要求を受け取るプロセッサーは割り込み要求に応答するため現在のアプリケーションスレッドの実行を直ちに中断します。
通常の動作を停止するため、割り込み率が高ければシステムのパフォーマンスが著しく低下する可能性があります。割り込みの親和性を設定する、または優先度の低い複数の割り込みを一つのバッチ (複数の割り込みをまとめる) にして送信することで割り込みにかかる時間を低減することが可能です。
割り込み要求の調整については「AMD64 および Intel 64 での割り込み親和性の設定」または「Tuna を使った CPU、スレッド、割り込みの親和性の設定」を参照してください。ネットワーク割り込みの詳細については「9章ネットワーク」を参照してください。

このページには機械翻訳が使用されている場合があります (詳細はこちら)。