ZEAM開発ログ v.0.3.7.1 Linux PC サーバーでGPU駆動ベンチマークを実行してみた

ZACKY こと山崎進です。

FAISの研究費で購入させていただいたPCサーバーに Linux をインストールして GPU 駆動ベンチマークを実行しました。ようやく期待した通りの性能が得られました！

[「ZEAM開発ログ 目次」はこちら](https://qiita.com/zacky1972/items/70593ab2b70d192813df)

# 前回までのあらすじ〜今回の動機

[「ZEAM開発ログ v.0.3.7 Windows PC サーバーでGPU駆動ベンチマークを実行してみた」](https://qiita.com/zacky1972/items/75282e7579e5aebb3229) では，FAISの研究費で購入させていただいたPCサーバーに Windows 10 をインストールして GPU 駆動ベンチマークを実行したのですが，Mac Pro (Mid 2010 アップグレード後) に負けるなど，期待外れに終わりました。

その後，ソースコードインストールを試みたのですが，Windows での開発に慣れなさすぎて全然うまくいきませんでした。

最近になってようやく Linux (Ubuntu) をインストールしたので，リベンジしたいと思います！

[Elixirのインストール方法はこちら
「Linux (Ubuntu 16.04) での exenv / erlenv を用いた Elixir / Erlang のソースコードインストール」](https://qiita.com/zacky1972/items/338baab1ccde12dcfab2)

# 使用した機材の仕様

## GPGPUサーバー ユニットコム UCGPU-E2630V4-32GB

* Processor: [2.20GHz Intel Xeon E5-2630 v4](https://ark.intel.com/ja/products/92981/Intel-Xeon-Processor-E5-2630-v4-25M-Cache-2_20-GHz) (プロセッサ数 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](https://ark.intel.com/JA/products/126793/Intel-Xeon-W-2195-Processor-24_75M-Cache-2_30-GHz) (プロセッサ数 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 での実行結果です。信頼のソースコードインストールです。

```bash
$ 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)

```bash
$ 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)

グレードアップ後:

```bash
$ 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サーバー

```bash
$ 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 で実行してみたいですね。