並列処理ライブラリを使った、ループ内で四則演算全部やるベンチマーク

今回はこれをやってみたい。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ループ内で四則演算全部やってみた．<br>1G回やったところで時間を出力する<br><br>Intel(R) Core(TM) i9-10900X CPU @ 3.70GHzで，g++ 9.3.0でオプションは-O3<br><br>四則演算全部だと5秒くらい．まあ割り算があるからしゃあないな <a href="https://t.co/fs9HxxJtKh">pic.twitter.com/fs9HxxJtKh</a></p>&mdash; 電子計算機の沼 (@Hishinuma_t) <a href="https://twitter.com/Hishinuma_t/status/1466228066741481474?ref_src=twsrc%5Etfw">December 2, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

サクサクっとソースを入力する。
```c++:arithmetic_bench.cpp
#include <iostream>
#include <omp.h>

int main(void){

  double a = 123.0;

  double time = omp_get_wtime();
  for(size_t i = 0; i < 100; i++){
    for(size_t j=0; j<1000000000; j++){
      a = (a * a - a) / (a + a);
    }
    std::cout << i << ": " << omp_get_wtime() - time << std::endl;
  }

  std::cout << a << std::endl;
  return 0;
}
```
ふぉぉぉ、C言語じゃなくてC++言語だ！！(いちいち驚くなよ)
なんか並列演算ライブラリ(OpenMP)も使われている！
これは普通の開発環境では入ってないはず。(ヨシ、入れよう)

```console:TERMINAL
benchmania@testmachine:$ sudo apt install libopenmpi3
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  libcaf-openmpi-3 libcoarrays-openmpi-dev libopenmpi-dev openmpi-bin
Suggested packages:
  openmpi-doc
The following NEW packages will be installed:
  libcaf-openmpi-3 libcoarrays-openmpi-dev libopenmpi-dev libopenmpi3 openmpi-bin
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/2914 kB of archives.
After this operation, 13.1 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Selecting previously unselected package libopenmpi3:amd64.
(Reading database ... 59742 files and directories currently installed.)
Preparing to unpack .../libopenmpi3_4.0.3-0ubuntu1_amd64.deb ...
Unpacking libopenmpi3:amd64 (4.0.3-0ubuntu1) ...
Selecting previously unselected package libcaf-openmpi-3:amd64.
Preparing to unpack .../libcaf-openmpi-3_2.8.0-1_amd64.deb ...
Unpacking libcaf-openmpi-3:amd64 (2.8.0-1) ...
Selecting previously unselected package openmpi-bin.
Preparing to unpack .../openmpi-bin_4.0.3-0ubuntu1_amd64.deb ...
Unpacking openmpi-bin (4.0.3-0ubuntu1) ...
Selecting previously unselected package libcoarrays-openmpi-dev:amd64.
Preparing to unpack .../libcoarrays-openmpi-dev_2.8.0-1_amd64.deb ...
Unpacking libcoarrays-openmpi-dev:amd64 (2.8.0-1) ...
Selecting previously unselected package libopenmpi-dev:amd64.
Preparing to unpack .../libopenmpi-dev_4.0.3-0ubuntu1_amd64.deb ...
Unpacking libopenmpi-dev:amd64 (4.0.3-0ubuntu1) ...
Setting up libopenmpi3:amd64 (4.0.3-0ubuntu1) ...
Setting up libcaf-openmpi-3:amd64 (2.8.0-1) ...
Setting up openmpi-bin (4.0.3-0ubuntu1) ...
update-alternatives: using /usr/bin/mpirun.openmpi to provide /usr/bin/mpirun (mpirun) in auto mode
update-alternatives: using /usr/bin/mpicc.openmpi to provide /usr/bin/mpicc (mpi) in auto mode
Setting up libcoarrays-openmpi-dev:amd64 (2.8.0-1) ...
Setting up libopenmpi-dev:amd64 (4.0.3-0ubuntu1) ...
update-alternatives: using /usr/lib/x86_64-linux-gnu/openmpi/include to provide /usr/include/x86_64-linux-gnu/mpi (mpi-x86_64-linux-gnu) in auto mode
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9.2) ...
benchmania@testmachine:~$
```
ではコンパイルしてみよう。まずは最適化オプションなし。
```console:test run
benchmania@testmachine:~$ g++ -fopenmp ./arithmetic_bench.cpp
benchmania@testmachine:~$ ./a.out
0: 9.92207
1: 19.7431
2: 32.0753
3: 41.9392
4: 52.155
5: 62.2154
6: 72.2766
7: 84.2037
8: 96.2158
9: 106.147
10: 116.282
11: 126.432
12: 136.449
13: 146.482
14: 156.457
15: 166.623
^C
```
だいたい１セットの実行に10秒ね。
さらに -O3 で最適化してみよう。
```console:optimized test run
benchmania@testmachine:~$ g++ -O3 -fopenmp ./arithmetic_bench.cpp
benchmania@testmachine:~$ ./a.out
0: 8.4418
1: 16.8531
2: 26.9274
3: 35.3909
4: 43.8322
5: 52.2763
6: 60.6712
7: 69.0874
8: 77.5814
9: 85.9656
10: 94.4131
11: 104.374
12: 112.859
13: 122.693
14: 131.091
15: 139.671
^C
```
だいたい15%～19%ぐらい高速化されるらしい。

先日組んだインテル12世代機でやってみる。
```console:Intel12Gen
benchmania@hoehoe:~/src/arithbench$ ./a.out
0: 6.98875
1: 13.9683
2: 20.9487
3: 27.9303
4: 34.9056
5: 41.8457
6: 48.7826
7: 55.7189
8: 62.6569
9: 69.5934
10: 76.5317
11: 83.4679
12: 90.4032
13: 97.3401
14: 104.278
15: 111.213
^C
```
Core i5-12400Fって結構速いんだな。
次に -O3 を試す。
```console:Intel12Gen -O3
benchmania@hoehoe:~/src/arithbench$ g++ -O3 -fopenmp ./arithmetic_bench.cpp
benchmania@hoehoe:~/src/arithbench$ ./a.out
0: 5.6175
1: 11.2248
2: 16.8331
3: 22.4449
4: 28.0554
5: 33.658
6: 39.2624
7: 44.8677
8: 50.4402
9: 56.065
10: 61.6759
11: 67.2941
12: 72.9113
13: 78.5323
14: 84.1524
15: 89.7686
^C
```
こちらはRyzen3600X機
```console:Ryzen 3600X
0: 6.48435
1: 12.9737
2: 19.4537
3: 25.94
4: 32.4245
5: 38.9101
6: 45.3993
7: 51.8871
8: 58.3728
9: 64.8636
10: 71.3472
11: 77.8476
12: 84.3331
13: 90.8208
14: 97.3037
15: 103.793
^C
```

```console:Ryzen 3600X -O3
0: 4.55765
1: 9.11392
2: 13.6917
3: 18.2674
4: 22.8226
5: 27.3812
6: 31.9426
7: 36.5023
8: 41.0644
9: 45.6303
10: 50.1842
11: 54.7392
12: 59.2975
13: 63.8572
14: 68.4155
15: 72.9716
16: 77.5308
^C
```