SkylakeとEPYCの比較 : Bioinfomatics Applications(1)

SkylakeとEPYCの双方でいくつかのbioinfomatics applicationでベンチマークを取ってみました。

今回比較に使用したのは以下の4モデルです。

CPU コア数 クロック周波数(定格) クロック周波数(ターボ最大) クロック周波数(All Core Boost) 概算価格(Web上) ※
Xeon Gold 5118 12 2.3 GHz 3.2 GHz 2.7 GHz $1,273
Xeon Gold 6126 12 2.6 GHz 3.7 GHz 3.3 GHz $1,776
EPYC 7351 16 2.4 GHz 2.9 GHz 2.9 GHz > $1,100
EPYC 7401 24 2.0 GHz 3.0 GHz 2.8 GHz $1,850

※ XeonはIntelのWebサイトの希望カスタマー価格から、EPYCはanandatech のWebサイトから

numactlで見るEPYCの特徴

性能面を考慮するときにコア数が多いという点は大きな特徴なのですが、
OSからは8コア単位で別のCPUコアとして認識されるため少し注意が必要です。

例えば、Dual CPU構成のマシンにおいてnumactl -H をXeonで実行した時、
下記のようになり、node0がCPU0、node1がCPU1を示しているのですが、

Xeon

# numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
node 0 size: 96938 MB
node 0 free: 87276 MB
node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 98304 MB
node 1 free: 92604 MB
node distances:
node   0   1 
  0:  10  21 
  1:  21  10

EPYC

EPYCの場合はDaul CPU構成でも下記のようになりまるで4coreのCPUを8個搭載しているように見えます。
末尾のnode distancesの行列は各コア間のメモリへのアクセスの相対的距離を示しているのですが
EPYCの場合はXeonに比べて同じ物理CPU間でも(node0 – node3)の間でも距離が生じ、物理的に遠いCPUの
メモリにアクセスした場合の距離はXeonに比べて1.5倍ほどになっています。

# numactl -H
available: 8 nodes (0-7)
node 0 cpus: 0 1 2 3
node 0 size: 65444 MB
node 0 free: 40188 MB
node 1 cpus: 4 5 6 7
node 1 size: 65535 MB
node 1 free: 41572 MB
node 2 cpus: 8 9 10 11
node 2 size: 65535 MB
node 2 free: 41057 MB
node 3 cpus: 12 13 14 15
node 3 size: 65535 MB
node 3 free: 41075 MB
node 4 cpus: 16 17 18 19
node 4 size: 65535 MB
node 4 free: 41153 MB
node 5 cpus: 20 21 22 23
node 5 size: 65535 MB
node 5 free: 41604 MB
node 6 cpus: 24 25 26 27
node 6 size: 65535 MB
node 6 free: 39944 MB
node 7 cpus: 28 29 30 31
node 7 size: 65535 MB
node 7 free: 41523 MB
node distances:
node   0   1   2   3   4   5   6   7 
  0:  10  16  16  16  32  32  32  32 
  1:  16  10  16  16  32  32  32  32 
  2:  16  16  10  16  32  32  32  32 
  3:  16  16  16  10  32  32  32  32 
  4:  32  32  32  32  10  16  16  16 
  5:  32  32  32  32  16  10  16  16 
  6:  32  32  32  32  16  16  10  16 
  7:  32  32  32  32  16  16  16  10 

ベンチマーク1 : Bowtie2-2.3.1

全コア使用時の比較

bowtieのベンチマークとは書きましたが、
sraファイルを取ってきてfastqを生成し、bowtie 〜 samtoolsを実行してbamファイルを生成してインデックスをつけるところまでを
一連のスクリプトで実行した場合のそれぞれの実行時間(単位:秒)です。
マルチスレッドに対応しているコマンドは全コア使用して実行するようにしています。

Xeon 5118 (24thr) Xeon 6126 (24thr) EPYC 7351 (32thr) EPYC 7401 (48thr)
fastq-dump(1thr) 286.97 241.44 295.52 280.88
bowtie2-build(All threads) 1040.15 883.99 1380.66 1374.31
bowtie2(All threads) 1138.18 982.78 904.81 672.82
sam2bam(All threads) 274.47 236.21 309.12 173.46
sam index(1thr) 133.30 109.04 131.43 124.93
合計(秒) 2873.07 2453.46 3021.54 2626.40

合計時間ではXeonが若干優位ですが、これはbowtie2-buildの実行時間に大きな差が生じていることが原因です。
bowtie2に限ってみればコア数の多さも手伝ってEPYCが優位という結果となりました。

EPYC: bind有無による性能比較

上で書いたnumactlの件があったので、
numactlでcpu,memoryをbindした場合としない場合の比較をしてみました。
bindした方の実行コマンドは以下の通りです。

  • 4thread # numactl --cpubind=0 --membind=0 bowtie2 -p 4 -x hg19chr_build -1 SRR067579_1.fastq -2 SRR067579_2.fastq -S SRR067579.sam
  • 8thread # numactl --cpubind=0,1 --membind=0,1 bowtie2 -p 8 -x hg19chr_build -1 SRR067579_1.fastq -2 SRR067579_2.fastq -S SRR067579.sam
  • 16thread # numactl --cpubind=0,1,2,3 --membind=0,1,2,3 bowtie2 -p 16 -x hg19chr_build -1 SRR067579_1.fastq -2 SRR067579_2.fastq -S SRR067579.sam
EPYC 7351(no bind) EPYC 7351 (bind)
4 threads 6238.84 5471.70
8 threads 3368.63 2871.93
16 threads 1905.74 1488.22
32 threads 904.81

bindするしないでかなりの差が出ました。
(Xeonでも測定はしましたがbind/no bindいずれもほとんど変わらない結果でした。)

このあたりは、上記のメモリが遠いことも関係してそうですし
OS/kernel周りの最適化などでEPYC向けの最適化が進めばもう少しましになるのではないかと期待したいですが、
現状ではbindしないことによるペナルティが大きいです。

ベンチマーク2 : BWA-0.7.17

全コア使用時の比較

bwaもbowtie2同様、fastq-dump〜bwa〜samtoolsの処理を一連のスクリプトにして実行した各実行結果です。

Bowtie Xeon 5118 Xeon 6126 EPYC 7351 EPYC 7401
fastq-dump(1thr) 124.66 103.15 133.93 131.68
bwa index(1thr) 261.49 227.23 228.07 231.14
bwa mem(All threads) 413.93 360.47 468.24 314.18
sam2bam(All threads) 64.85 56.85 59.45 54.48
sam index(1thr) 52.69 43.85 51.05 48.46
合計(秒) 917.62 791.55 940.74 779.94

EPYC: bind有無による性能比較

こちらもbowtie2同様にEPYC 7351を使ってbind/no bindで測定しました。
bowtie2ほどでは無いにせよ、1割前後の性能差が出ています。

EPYC 7351(numa) EPYC 7351(no-numa)
4 threads 2251.20 2671.92
8 threads 1239.04 1368.78
16 threads 670.60 714.75
32 threads 468.24

ベンチマーク3 : Stream Benchmark

bioinfomaticsのアプリケーションでは無いのですが、
冒頭のnumactlの結果を見るとやはりメモリのアクセス速度のところの性能差がどのようになるのか
気になるのではないかと思いますので載せてみます。(単位:MB/s)

メモリの仕様に関してですが、
SkylakeはCPUあたり6チャネル、EPYCはCPUあたり8チャネルを持っています。
メモリ動作速度の最大はどちらも2666MHzです。

Skylake
numa Copy Scale Add Triad 説明
numactl –cpubind=0 –membind=0(16core/96G) 64409.9 64554.2 72856.2 72906.3 同一ソケット内でのメモリアクセス
numactl –cpubind=0 –membind=1(16core/96G) 33926.9 33933.1 34168.7 34161.8 遠い方のメモリへのアクセス
no numa(32core/192G) 129168.4 129021.6 145590.5 145569.8 BindせずDual Socketの全コア使用
EPYC
numa Copy Scale Add Triad 説明
numactl –cpubind=0 –membind=0(4core/64G) 23979.4 23771.1 26700.0 26728.0 同一ソケット内の同一node
numactl –cpubind=0,1 –membind=0,1(8core/128G) 47986.7 47878.3 52967.8 53028.5 同一ソケット内の2node使用時
numactl –cpubind=0,1,2,3 –membind=0,1,2,3(16core/256G) 95562.5 95557.8 105311.1 105500.6 同一ソケット内の全コア使用時
no numa(32core/512G) 135144.3 134846.0 141459.4 142717.5 BindせずDual Socketで全コア使用

Skylakeの場合、bindせずに全コア使用した場合のメモリ帯域が、同一ソケット内でのメモリ帯域の2倍になっていることから
明示的にbindしなくても自動的に近い方のメモリアクセスをするようになっているということが上記の結果からわかります。

反面、EPYCの場合、Single Socketの結果から、Dual Socketでは200GB/s近いメモリ帯域が出るのではいないかという期待が膨らむものの
実際にはSkylakeと同程度の帯域しか得られませんでした。このあたりはOS/Kernel周りの最適化で今後改善されるか期待を持ってみたいと思います。