2.4. 割り込みおよびプロセスバインディング
リアルタイム環境では、さまざまなイベントに応答する際にレイテンシーを最小限に抑える必要があります。理想的には、割り込み (IRQ) およびユーザープロセスを異なる専用の CPU で相互に分離することができます。
通常、割り込みは CPU 間で均等に共有されます。これにより、新しいデータおよび命令キャッシュの書き込みによって割り込み処理が遅延し、CPU で発生する他の処理との競合が発生することがよくあります。この問題を回避するには、時間クリティカルな割り込みとプロセスを CPU (または CPU の範囲) 専用にすることができます。このようにして、この割り込みの処理に必要なコードおよびデータ構造は、プロセッサーデータと命令キャッシュ内に可能な限り高い可能性が高くなります。その後、専用プロセスはできるだけ迅速に実行でき、その他のタイムクリティカルなプロセスはすべて残りの CPU 上で実行されます。これは、関係する速度がメモリーの制限や、境界バス帯域幅で利用可能な場合に特に重要になります。ここでは、メモリーをプロセッサーキャッシュにフェッチする待機時間は、全体的な処理時間と決定論に影響します。
実際には、最適なパフォーマンスはアプリケーションによって異なります。たとえば、同様の機能を実行する複数の異なるオペラのチューニングでは、最適なパフォーマンスチューニングが完全に異なります。1 つ目は、オペレーティングシステムの機能および割り込み処理のために 4 つの CPU のうち 2 つを分離し、残りの 2 つの CPU をアプリケーションの処理用にのみ提供することが最適でした。別の環境では、ネットワーク関連のアプリケーションプロセスを、ネットワークデバイスドライバーの割り込みを処理する CPU にバインドすると、最適な決定論が発生しました。最終的に、チューニングは、さまざまな設定を行い、組織に最適なものを見つけます。
重要
ここで説明するプロセスの多くは、所定の CPU または範囲の CPU マスクを把握する必要があります。CPU マスクは、通常 32 ビットマスクで表されます。また、使用するコマンドに応じて、数字または 16 進数で表現することもできます。たとえば、CPU 0 の CPU マスクは ビットマスクとして
00000000000000000000000000000001
、10 進数 として 1
、および 16 進数として 0x00000001
となります。CPU 0 と 1 の両方の CPU マスクは、ビットマスクとして 00000000000000000000000000000011
、10 進数として 3
、16 進数として 0x00000003
となります。
手順2.3 irqbalance
デーモンの無効化
このデーモンはデフォルトで有効になっており、割り込みの処理を CPU で定期的に強制します。ただし、リアルタイムのデプロイメントでは、アプリケーションは通常特定の CPU にバインドされるため、
irqbalance
デーモンは必要ありません。
irqbalance
デーモンのステータスを確認します。systemctl status irqbalance
~]# systemctl status irqbalance irqbalance.service - irqbalance daemon Loaded: loaded (/usr/lib/systemd/system/irqbalance.service; enabled) Active: active (running) …
Copy to Clipboard Copied! irqbalance
デーモンが実行している場合は停止します。systemctl stop irqbalance
~]# systemctl stop irqbalance
Copy to Clipboard Copied! - システムの起動時に
irqbalance
が再起動しないことを確認します。systemctl disable irqbalance
~]# systemctl disable irqbalance
Copy to Clipboard Copied!
手順2.4 IRQ バランスからの CPU の除外
/etc/sysconfig/irqbalance
設定ファイルには、ISRQ balacing サービスによって CPU を考慮から除外できる設定が含まれています。このパラメーターには IRQBALANCE_BANNED_CPUS
という名前が付けられ、64 ビットの 16 進数ビットマスクです。マスクの各ビットは CPU コアを表します。
たとえば、16 コアシステムを実行している場合、CPU 8 から 15 を IRQ バランシングから削除する場合は、以下を実行します。
- 希望するテキストエディターで
/etc/sysconfig/irqbalance
を開き、IRQBALANCE_BANNED_CPUS
というタイトルが付いたファイルのセクションを見つけます。IRQBALANCE_BANNED_CPUS 64 bit bitmask which allows you to indicate which cpu's should be skipped when reblancing irqs. Cpu numbers which have their corresponding bits set to one in this mask will not have any irq's assigned to them on rebalance
# IRQBALANCE_BANNED_CPUS # 64 bit bitmask which allows you to indicate which cpu's should # be skipped when reblancing irqs. Cpu numbers which have their # corresponding bits set to one in this mask will not have any # irq's assigned to them on rebalance # #IRQBALANCE_BANNED_CPUS=
Copy to Clipboard Copied! - この方法で変数
IRQBALANCE_BANNED_CPUS
のコメントを解除し、その値を設定して CPU 8 から 15 を除外します。IRQBALANCE_BANNED_CPUS=0000ff00
IRQBALANCE_BANNED_CPUS=0000ff00
Copy to Clipboard Copied! - これにより、
irqbalance
プロセスはビットマスクでビットが設定された CPU を無視します。この場合、ビットは 8 ~ 15 になります。 - 最大 64 個の CPU コアを持つシステムを実行している場合は、それぞれ 8 桁の 16 進数の数値をコンマで区切ります。
IRQBALANCE_BANNED_CPUS=00000001,0000ff00
IRQBALANCE_BANNED_CPUS=00000001,0000ff00
Copy to Clipboard Copied! 上記のマスクは、CPU 8 から 15、および CPU 33 を IRQ バランシングから除外します。
注記
RedHat EnterpriseLinux 7.2 では、この
irqbalance
ツールは、IRQBALANCE_BANNED_CPUS
が /etc/sysconfig/irqbalance
ファイルに設定されていない場合に isolcpus=
カーネルパラメーターを介して分離された CPU コア上の IRQ を自動的に回避します。
手順2.5 個々の IRQ への CPU アフィニティーの手動割り当て
/proc/interrupts
ファイルを参照して、各デバイスが使用している IRQ を確認します。cat /proc/interrupts
~]# cat /proc/interrupts
Copy to Clipboard Copied! このファイルには IRQ の一覧が含まれています。各行には、ISRQ 番号、各 CPU で発生した割り込みの数と、その後に IRQ タイプと説明が表示されます。CPU0 CPU1 0: 26575949 11 IO-APIC-edge timer 1: 14 7 IO-APIC-edge i8042 ...[output truncated]...
CPU0 CPU1 0: 26575949 11 IO-APIC-edge timer 1: 14 7 IO-APIC-edge i8042 ...[output truncated]...
Copy to Clipboard Copied! - IRQ が 1 つのプロセッサーでのみ実行されるように指示するには、
echo
コマンドを使用して CPU マスク(16 進数)を特定の IRQ のsmp_affinity
エントリーに書き込みます。この例では、IRQ 番号 142 の割り込みを CPU 0 でのみ実行するよう指示しています。echo 1 > /proc/irq/142/smp_affinity
~]# echo 1 > /proc/irq/142/smp_affinity
Copy to Clipboard Copied! - この変更は、割り込みが発生した場合にのみ有効になります。設定をテストするには、ディスクアクティビティーを生成し、
/proc/interrupts
ファイルを変更して変更を確認します。割り込みが発生したと仮定すると、選択した CPU の割り込み数が増加し、他の CPU の番号が変更されていないことがわかります。
手順2.6 taskset
ユーティリティーを使用してプロセスの CPU にバインド
この
taskset
ユーティリティーは、タスクのプロセス ID (PID) を使用してアフィニティーを表示または設定します。または、選択した CPU アフィニティーでコマンドを起動するために使用できます。アフィニティーを設定するには taskset
は、CPU マスクを 10 進数または 16 進数で表記する必要があります。マスクの引数は、コマンドまたは変更される PID に対してどの CPU コアが有効なかを指定するビットマスクです。
- 現在実行していないプロセスのアフィニティーを設定するには、
taskset
を使用して CPU マスクとプロセスを指定します。こので例は、my_embedded_process
は、CPU 3 のみを使用するように指示されています (CPU マスクの 10 進数バージョンを使用)。taskset 8 /usr/local/bin/my_embedded_process
~]# taskset 8 /usr/local/bin/my_embedded_process
Copy to Clipboard Copied! - ビットマスクで複数の CPU を指定することもできます。この例では、
my_embedded_process
は、プロセッサー 4、5、6、および 7 で実行するように指示されています (CPU マスクの 16 進数バージョンを使用)。taskset 0xF0 /usr/local/bin/my_embedded_process
~]# taskset 0xF0 /usr/local/bin/my_embedded_process
Copy to Clipboard Copied! - さらに、
-p
(--pid
) オプションと CPU マスクと、変更するプロセスの PID を使用して、すでに実行しているプロセスの CPU アフィニティーを設定できます。この例では、PID が 7013 のプロセスは CPU 0 でのみ実行されるように指示されています。taskset -p 1 7013
~]# taskset -p 1 7013
Copy to Clipboard Copied! - 最後に、
-c
パラメーターを使用して、CPU マスクの代わりに CPU リストを指定できます。たとえば、CPU 0、4、CPU 7、および CPU 7 から 11 を使用するには、コマンドラインに-c 0,4,7-11
が含まれます。ほとんどの場合、この呼び出しは便利です。
重要
この taskset ユーティリティーは NUMA(Non-Uniform Memory Access) システムで機能しますが、ユーザーが CPU と 最も近い NUMA メモリーノードにスレッドをバインドすることはできません。このようなシステムでは、taskset は推奨されるツールではなく、numactl ユーティリティーをその高度な機能に使用する必要があります。詳細は、「非非統合メモリーアクセス」 を参照してください。
関連する man ページ
詳細は、以下の man ページは本セクションに記載の情報に関連しています。
- chrt(1)
- taskset(1)
- nice(1)
- renice(1)
- Linux スケジューリングスキームの説明の sched_setscheduler(2)。