Amazon Linux で、Hyper-Threading を無効化する方法

2017.11.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

EC2 インスタンスを稼働させる AWS 基盤(仮想ホストサーバー)では、インテル®︎ ハイパースレッディング・テクノロジー(以降、HT)が利用可能な Xeon プロセッサーが利用されております。HT については、インテル社の公式サイトをご確認ください。

2017/10 現在、AWS から提供されている EC2 インスタンスの仮想CPU 数は、論理コア数に相当しているため仮想CPU 数を 1/2 した個数分の物理コアが割り当てられていると理解できます。ただし、一部(※)の特定インスタンスを除きます。

本記事では、Amazon Linux を利用した場合に OS インスタンス上から HT設定を無効化(つまり、仮想CPU 数を 1/2 した物理コア数に変更)する方法についてご紹介します。

HT の設定を無効化する場合のユースケースですが、以下の資料にて FPU heavy なアプリケーション(つまり、浮動⼩数点演算が多いアプリ)を利用する場合であることが紹介されております。

前提

本記事では、以下の環境を想定し検証を実施しました。

  • c4.xlarge
  • Amazon Linux AMI 2017.09.1 (HVM), SSD Volume Type - ami-2803ac4e

なお、Linux 環境では CPU番号は 物理CPUコア → 物理CPUコア → 論理CPUコア → 論理CPUコア の順に並び Windows 環境の場合は、インターリーブされるようです。(つまり 物理CPUコア → 論理CPUコア → 物理CPUコア → 論理CPUコア のように交互に配置される)

設定方法

一時的に設定を変更(無効化)するには、以下のコマンドを実行します。(インデックスの番号は、環境に合わせて置き換えが必要) 設定するコア数が少なければインデックス番号は直接指定で問題ありません。

$ sudo su -
# for i in `seq <無効化設定するCPU番号の開始インデックス> <無効化設定するCPU番号の終了インデックス>`; do
echo 0 > /sys/devices/system/cpu/cpu${i}/online
done

無効化した設定を再度有効化するには、/sys/devices/system/cpu/cpuX/online に対して "1" を設定するか EC2 インスタンスを再起動するだけです。

恒久的に HyperThreading を無効化したい場合は、カーネルのブートパラメータに maxcpu=<物理コア数>の設定を追加し EC2 インスタンスを再起動します。

$ sudo su -
# grubby --info=ALL
index=0
kernel=/boot/vmlinuz-4.9.58-18.55.amzn1.x86_64
args="console=tty1 console=ttyS0 selinux=0 nvme_core.io_timeout=4294967295"
root=LABEL=/
initrd=/boot/initramfs-4.9.58-18.55.amzn1.x86_64.img
# grubby --args "maxcpus=2" --update-kernel /boot/vmlinuz-4.9.58-18.55.amzn1.x86_64
# grubby --info=ALL
index=0
kernel=/boot/vmlinuz-4.9.58-18.55.amzn1.x86_64
args="console=tty1 console=ttyS0 selinux=0 nvme_core.io_timeout=4294967295 maxcpus=2"
root=LABEL=/
initrd=/boot/initramfs-4.9.58-18.55.amzn1.x86_64.img
# shutdown -r now

では、検証してみます。

実機検証

まずは、c4.xlarge インスタンスを起動し lscpu(1) で構成されている CPU リソースを確認します。

$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz
Stepping: 2
CPU MHz: 2900.004
BogoMIPS: 5876.97
Hypervisor vendor: Xen
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 25600K
NUMA node0 CPU(s): 0-3

上記の情報から、1 Socket / 2 Core / 4 Thread のリソースが構成されていることが確認できます。 次に、詳細情報を確認していきます。

$ cat /proc/cpuinfo | grep -e 'core id' -e processor
processor : 0
core id : 0
processor : 1
core id : 1
processor : 2
core id : 0
processor : 3
core id : 1

上記の情報から、以下であると推測できます。

CPU番号 物理コア番号
CPU#0 物理コア#0
CPU#1 物理コア#1
CPU#2 物理コア#0(の論理コア)
CPU#3 物理コア#1(の論理コア)

では、論理コアのペアを確認してみます。

$ cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list \
> | sort --unique --numeric-sort
0,2
1,3

CPU#0 - CPU#2 および CPU#1 - CPU#3 がそれぞれ同じ物理コアであることが確認できました。 そのため、本記事では CPU#2 および CPU#3 を無効化します。

$ sudo su -
# for i in 2 3
echo 0 > /sys/devices/system/cpu/cpu${i}/online
done

CPU#2 および #3 をオフラインに設定しました。状態を確認してみます。

$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0,1
Off-line CPU(s) list: 2,3 ★オフラインに変更されている
Thread(s) per core: 1
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz
Stepping: 2
CPU MHz: 2900.004
BogoMIPS: 5876.93
Hypervisor vendor: Xen
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 25600K
NUMA node0 CPU(s): 0,1

問題なく変更されているようです。 ちなみに、コアあたりのスレッド数が "2" から "1" に変わっています。

最後に

AWS 基盤側の技術的な詳細情報ってあまり公開されていないんだろうなーと勝手に思い込んでいましたが、今更ながら昨年の re:Invent にて Deep Dive on Amazon EC2 Instances という資料が公開されていることに気付き驚きました。なお、弊社では今年も AWS re:Invent 2017 に参加致します。なんと今年は、34名が現地での参加となります。

AWS re:Invent 2017 が気になる読者の方は、以下の記事も合わせて参照頂けると幸いです。

ではでは

参考情報