ZACKY こと山崎進です。
FAISの研究費で購入させていただいたPCサーバーに Linux をインストールして GPU 駆動ベンチマークを実行しました。ようやく期待した通りの性能が得られました!
前回までのあらすじ〜今回の動機
「ZEAM開発ログ v.0.3.7 Windows PC サーバーでGPU駆動ベンチマークを実行してみた」 では,FAISの研究費で購入させていただいたPCサーバーに Windows 10 をインストールして GPU 駆動ベンチマークを実行したのですが,Mac Pro (Mid 2010 アップグレード後) に負けるなど,期待外れに終わりました。
その後,ソースコードインストールを試みたのですが,Windows での開発に慣れなさすぎて全然うまくいきませんでした。
最近になってようやく Linux (Ubuntu) をインストールしたので,リベンジしたいと思います!
Elixirのインストール方法はこちら
「Linux (Ubuntu 16.04) での exenv / erlenv を用いた Elixir / Erlang のソースコードインストール」
使用した機材の仕様
GPGPUサーバー ユニットコム UCGPU-E2630V4-32GB
- Processor: 2.20GHz Intel Xeon E5-2630 v4 (プロセッサ数 2 物理コア数 10コア x 2,論理コア数 20コア x 2)
- Memory: 32 GB 2400 MHz DDR4
- Graphics: NVIDIA GeForce GTX 1080 Ti
- OS
- Ubuntu (16.04)
iMac Pro に迫るスペックです。コア数は本GPGPUサーバーの方が多く,クロックはiMac Proの方が若干高い,世代はiMac Proの方が1つ新しい,という感じです。グラフィックボードは iMac Pro 搭載の Radeon Pro Vega 64 よりも GPGPUサーバー搭載の NVIDIA GeForce GTX 1080 Ti の方が処理能力が高いと言われています。
予想としては pure Elixir だとコア数の多いGPGPUサーバーの方が有利で,ネイティブコードが入ると iMac Pro の方が有利,GPU駆動はGPGPUサーバーが優勢と見ましたが,果たして結果はいかに?
参考: iMac Pro (2017)
- Processor: 2.3 GHz Intel Xeon W (プロセッサ数 1,物理コア18,論理コア36)
- Memory: 32 GB 2666 MHz DDR4
- Graphics: Radeon Pro Vega 64 16368MB
- SSD (BlackMagic)
- Write 2980.3MB/s
- Read 2465.1MB/s
CPUとGPUは最高性能の構成,メモリとSSDは標準構成です。
参考: Mac Pro (Mid 2010)
- Processor:
- グレードアップ前: 2.8 GHz Quad-Core Intel Xeon (プロセッサ数 1,物理コア数 4,論理コア数8)
- グレードアップ後: 2 x 3.46 GHz 6-Core Intel Xeon (プロセッサ数 2,物理コア数 6 x 2,論理コア数 12 x 2)
- Memory: 16 GB 1066 MHz DDR3
- Graphics: ATI Radeon HD 5770 1024MB
- SSD (BlackMagic)
- Write 473.9MB/s
- Read 507.4MB/s
CPUが最強構成になりました。
ベンチマーク結果
Elixir 1.7.3 での実行結果です。信頼のソースコードインストールです。
$ elixir -v
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:40:40] [ds:40:40:10] [async-threads:1] [hipe] [sharing-preserving]
Elixir 1.7.3 (compiled with Erlang/OTP 21)
$
stages | benchmarks1 | benchmarks3 | benchmarks8 |
---|---|---|---|
pure Elixir | pure Elixir | Elixir/Rustler | |
loop | inlining inside of Flow.map | loop, passing by list, with Window | |
1 | 41.786277 | 29.282312 | 6.296205 |
2 | 19.828726 | 17.852154 | 33.133127 |
4 | 12.437972 | 12.173246 | 24.639352 |
8 | 6.876529 | 7.289417 | 25.940939 |
16 | 6.382543 | 6.659193 | 30.128286 |
32 | 6.513086 | 6.110929 | 35.145780 |
64 | 6.779863 | 6.737389 | 40.890980 |
128 | 7.955085 | 7.007284 | 53.373573 |
benchmarks_g2 | benchmarks_t1 | benchmarks_empty |
---|---|---|
Elixir/Rustler | Elixir/Rustler | Elixir/Rustler |
OpenCL(GPU), inlining | rayon | Ruslter empty |
1.131473 | 0.82456 | 1.092245 |
Rust CPU | Rust OpenCL | Rust rayon |
---|---|---|
Rust | Rust | Rust |
CPU(1), loop | OpenCL(GPU), inlining | CPU(multi), loop |
1.598269 | 0.703870 | 0.210771 |
参考: iMac Pro (2017)
$ elixir -v
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:36:36] [ds:36:36:10] [async-threads:1] [hipe] [sharing-preserving]
Elixir 1.7.3 (compiled with Erlang/OTP 21)
stages | benchmarks1 | benchmarks3 | benchmarks8 |
---|---|---|---|
pure Elixir | pure Elixir | Elixir/Rustler | |
loop | inlining inside of Flow.map | loop, passing by list, with Window | |
1 | 20.560353 | 15.633272 | 4.615349 |
2 | 10.936360 | 8.836433 | 15.333913 |
4 | 6.192533 | 5.520968 | 11.213617 |
8 | 3.955429 | 4.440325 | 10.882564 |
16 | 4.349171 | 4.273822 | 12.157997 |
32 | 4.465429 | 4.089763 | 14.664140 |
64 | 4.685076 | 4.069384 | 20.075830 |
128 | 4.175054 | 4.442996 | 28.437392 |
benchmarks_g2 | benchmarks_t1 | benchmarks_empty |
---|---|---|
Elixir/Rustler | Elixir/Rustler | Elixir/Rustler |
OpenCL(GPU), inlining | rayon | Ruslter empty |
1.229529 | 0.686809 | 0.861733 |
Rust CPU | Rust OpenCL | Rust rayon |
---|---|---|
Rust | Rust | Rust |
CPU(1), loop | OpenCL(GPU), inlining | CPU(multi), loop |
1.212508 | 0.707200 | 0.251875 |
pure Elixir,シングルCPU,Rustler/GPU,Rustler/マルチCPUだと iMac Pro の方が速いですが,Rust/GPUは互角,Rust/マルチCPUだとGPGPUサーバーの方が速いという結果が得られました!
参考: Mac Pro (Mid 2010)
グレードアップ後:
$ elixir -v
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:24:24] [ds:24:24:10] [async-threads:1] [hipe] [sharing-preserving]
Elixir 1.7.3 (compiled with Erlang/OTP 21)
stages | benchmarks1 | benchmarks3 | benchmarks8 |
---|---|---|---|
pure Elixir | pure Elixir | Elixir/Rustler | |
loop | inlining inside of Flow.map | loop, passing by list, with Window | |
1 | 38.917572 | 31.239018 | 6.494845 |
2 | 19.393174 | 16.961465 | 24.924447 |
4 | 11.407064 | 9.539546 | 21.095470 |
8 | 6.688697 | 6.853216 | 19.004524 |
16 | 6.131300 | 6.378301 | 22.143169 |
32 | 7.132144 | 6.755734 | 29.062707 |
64 | 7.465966 | 9.032967 | 36.798732 |
128 | 7.672280 | 7.007284 | 50.207617 |
benchmarks_g2 | benchmarks_t1 | benchmarks_empty |
---|---|---|
Elixir/Rustler | Elixir/Rustler | Elixir/Rustler |
OpenCL(GPU), inlining | rayon | Ruslter empty |
1.484173 | 1.089455 | 1.905256 |
Rust CPU | Rust OpenCL | Rust rayon |
---|---|---|
Rust | Rust | Rust |
CPU(1), loop | OpenCL(GPU), inlining | CPU(multi), loop |
2.456480 | 0.900843 | 0.365043 |
pure Elixirは互角ですが,それ以外はGPGPUサーバーの方が速いです!
参考 Windows GPGPUサーバー
$ elixir -v
Erlang/OTP 21 [erts-10.0.1] [64-bit] [smp:40:32] [ds:40:32:10] [async-threads:1]
Elixir 1.7.3 (compiled with Erlang/OTP 19)
stages | benchmarks1 | benchmarks3 | benchmarks8 |
---|---|---|---|
pure Elixir | pure Elixir | Elixir/Rustler | |
loop | inlining inside of Flow.map | loop, passing by list, with Window | |
1 | 42.188 | 29.703 | 7.922 |
2 | 20.875 | 21.938 | 24.047 |
4 | 11.500 | 10.750 | 16.797 |
8 | 8.891 | 8.421 | 19.187 |
16 | 8.578 | 12.110 | 21.938 |
32 | 9.156 | 8.453 | 21.562 |
64 | 13.328 | 9.156 | 23.219 |
128 | 9.875 | 12.969 | 26.187 |
benchmarks_g2 | benchmarks_t1 | benchmarks_empty |
---|---|---|
Elixir/Rustler | Elixir/Rustler | Elixir/Rustler |
OpenCL(GPU), inlining | rayon | Ruslter empty |
2.109 | 1.625 | 1.531 |
Rust CPU | Rust OpenCL | Rust rayon |
---|---|---|
Rust | Rust | Rust |
CPU(1), loop | OpenCL(GPU), inlining | CPU(multi), loop |
1.859367 | 1.343743 | 0.453128 |
pure Elixir の stages が多い場合,Rustler / Rust 全般で速度が向上しました!
考察
最初に立てた予想と見比べましょう。
予想としては pure Elixir だとコア数の多いGPGPUサーバーの方が有利で,ネイティブコードが入ると iMac Pro の方が有利,GPU駆動はGPGPUサーバーが優勢と見ましたが,果たして結果はいかに?
結果としては,pure Elixir は iMac Pro の方が速く,ネイティブコードのマルチコアは GPGPUサーバーの方が速く,そのほかは互角,というような感じでした。
pure Elixir が予想に反して GPGPU サーバーが遅かったのはなんでですかね? 考えられるのは,Linux 版の Elixir / Erlang にパフォーマンス上のボトルネックがあるのか,ErlangVMの特性が CPU アーキテクチャによって変わってくるのか,というところですかね。このあたりは,iMac Pro に Linux をインストールしてみたら何かわかるかもしれませんね。
pure Elixir で stages が多い場合とネイティブコードのマルチコアで, GPGPU サーバーの速度がぐんと伸びるのは,コア数が多いことが効いているのだと思います。
Rust のマルチコアは GPGPU サーバーの方が速く,Rustler のマルチコアが iMac Pro の方が速いのは,Linux のスレッド生成が遅いためと,Rust ではスレッドプールが効いているが Rustler ではきいていないことが考えられます。
やはり Windows の Elixir バイナリは OTP19 だったんじゃないか疑惑があります。根拠としては,ネイティブコードが絡むと Linux の場合に速度向上があったことと,OTP19 → OTP21 で NIF の1msペナルティが緩和されるなどの改良があったことからです。
あと,GPU対決で,iMac Pro の Radeon Pro Vega 64 の方が GPGPUサーバーの NVIDIA GeForce GTX 1080 Ti より速いのは,グラフィックボードの性能差なのかもしれませんが,NVIDIA が OpenCL にあまり力を入れていないという「噂」の方を信じたくなります。GPU ベンチマークを CUDA で実行してみたいですね。