OpenMP > 最適化 > [32スレッド -> OMP_NUM_THREADSを4に制限して7並列化] > wall time [28.8時間]の処理が[4.6時間]に | link: topのload average

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2 
32GB RAM 
CentOS Linux release 7.7.1908 (Core)
```

WRF (Weather Research and Forecasting Model)関連。
WRFのあと処理の計算の最適化に関して。

## 背景

- CentOS 6.9で数値計算システムを構築していた
    - とある数値計算に18時間かかっていた
- CentOS 7.7で数値計算システムを再構築した結果
    - とある数値計算は28.8時間かかるようになった
    - cpuspeedなどの設定を見たが原因は分かっていない
    - 使用ライブラリのバージョン違いなどもあるが
- 18時間 -> 28.8時間の処理は18時間に戻せないだろうか
- OpenMPで処理している
- Xeon (8コア; 16スレッド) x 2 = 32スレッドを使っているか
- 2005年に64CPUで実施したような「最適な」計算にすると早くなるのでは?

## 最適な計算

- 並列計算はスレッド同士の通信量が問題となってくる
- スレッド数が増えると通信量が増え、本来の能力が発揮しにくくなる
    - 自身のタスクに集中できなくなる
- 2005年に取った方策
    - 64CPU (スパコン) @ India
    - 各CPUに対して異なる入力パラメータの計算をjob投入
    - 終了後に結果を統合する
    - CPUの使用率はほぼ100%で実施された
    - OpenMPIやMPICHを使う場合に比べて7倍くらい高速化した（と記憶している。14年前なのであやふやではあるが)

### OMP_NUM_THREADS

- [OpenMP* の環境変数](http://www2.kobe-u.ac.jp/~lerl2/l_cc_p_10.1.008/doc/main_cls/mergedProjects/optaps_cls/common/optaps_par_var.htm)
    - Note: 情報感謝です
    - OMP_NUM_THREADS
        - オペレーティング・システムで認識されるプロセッサー数

一つの設定パラメータにてOMP_NUM_THREADSを変更して計算してみた。

- OMP_NUM_THREADS=2:
    - 3分20秒
- OMP_NUM_THREADS=4:
    - 2分25秒
- OMP_NUM_THREADS=8:
    - 1分56秒
- OMP_NUM_THREADS=32 (従来の計算):
    - 2分06秒

OMP_NUM_THREADS=4にて7並列にすると、だいたい7倍くらいは早くなりそうか。
(システムの動作に影響がないように32スレッドすべてを使わないという考え）。

## 計算の様子

topコマンドで「1」を入力することで、CPUの稼働状況を確認できる。

- [link > Linux > top > 1 > スレッドごとの処理状況を表示](https://qiita.com/7of9/items/e788209b9806748fc03b)

### 最適化前 > 32スレッド使用

```
top - 08:41:29 up 9 days, 21:23,  1 user,  load average: 10.02, 5.47, 2.28
Tasks: 435 total,   2 running, 433 sleeping,   0 stopped,   0 zombie
%Cpu0  : 49.5 us,  1.3 sy,  0.0 ni, 48.8 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu1  : 54.1 us,  0.3 sy,  0.0 ni, 45.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  : 52.8 us,  0.3 sy,  0.0 ni, 46.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  : 51.0 us,  4.9 sy,  0.0 ni, 44.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  : 55.9 us,  4.0 sy,  0.0 ni, 40.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  : 56.3 us,  0.0 sy,  0.0 ni, 43.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  : 55.8 us,  0.0 sy,  0.0 ni, 44.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  : 55.9 us,  0.3 sy,  0.0 ni, 43.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu8  : 42.8 us,  0.0 sy,  0.0 ni, 57.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu9  : 42.1 us,  0.3 sy,  0.0 ni, 57.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu10 : 45.4 us,  0.3 sy,  0.0 ni, 54.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu11 : 55.4 us,  0.3 sy,  0.0 ni, 44.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu12 : 51.8 us,  0.3 sy,  0.0 ni, 47.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu13 : 46.0 us,  0.0 sy,  0.0 ni, 54.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu14 : 43.4 us,  0.3 sy,  0.0 ni, 56.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu15 : 43.4 us,  0.3 sy,  0.0 ni, 56.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu16 : 52.5 us,  0.3 sy,  0.0 ni, 47.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu17 : 57.6 us,  0.3 sy,  0.0 ni, 42.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu18 : 53.8 us,  0.3 sy,  0.0 ni, 45.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu19 : 50.7 us,  0.3 sy,  0.0 ni, 49.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu20 : 53.8 us,  0.0 sy,  0.0 ni, 46.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu21 : 56.6 us,  0.3 sy,  0.0 ni, 43.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu22 : 56.9 us,  0.3 sy,  0.0 ni, 42.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu23 : 56.2 us,  0.0 sy,  0.0 ni, 43.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu24 : 91.8 us,  1.3 sy,  0.0 ni,  6.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu25 : 55.3 us,  0.0 sy,  0.0 ni, 44.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu26 : 49.5 us,  0.3 sy,  0.0 ni, 50.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu27 : 48.2 us,  0.3 sy,  0.0 ni, 51.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu28 : 47.4 us,  0.3 sy,  0.0 ni, 52.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu29 : 38.6 us,  0.7 sy,  0.0 ni, 60.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu30 : 53.0 us,  0.3 sy,  0.0 ni, 46.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu31 : 46.4 us,  0.0 sy,  0.0 ni, 53.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 32642872 total, 16016892 free,  2429088 used, 14196892 buff/cache
KiB Swap: 16449532 total, 16443892 free,     5640 used. 29762312 avail Mem 
```

### 最適化後 > 4スレッド使用の7並列

```
top - 18:57:23 up 9 days,  7:39,  1 user,  load average: 11.43, 10.96, 10.31
Tasks: 445 total,   8 running, 437 sleeping,   0 stopped,   0 zombie
%Cpu0  : 42.8 us,  0.0 sy,  0.0 ni, 57.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  : 47.2 us,  0.7 sy,  0.0 ni, 52.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  : 38.1 us,  0.0 sy,  0.0 ni, 61.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  : 47.7 us,  0.7 sy,  0.0 ni, 51.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  : 27.7 us,  0.3 sy,  0.0 ni, 71.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  : 44.7 us,  1.0 sy,  0.0 ni, 54.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  : 48.3 us,  3.3 sy,  0.0 ni, 48.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  : 45.3 us,  4.0 sy,  0.0 ni, 50.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu8  : 54.0 us,  0.7 sy,  0.0 ni, 45.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu9  : 53.3 us,  0.0 sy,  0.0 ni, 46.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu10 : 50.7 us,  0.0 sy,  0.0 ni, 49.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu11 : 46.4 us,  0.3 sy,  0.0 ni, 53.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu12 : 51.8 us,  0.7 sy,  0.0 ni, 47.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu13 : 53.1 us,  0.0 sy,  0.0 ni, 46.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu14 : 48.7 us,  0.3 sy,  0.0 ni, 51.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu15 : 60.3 us,  0.7 sy,  0.0 ni, 39.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu16 : 55.0 us,  1.7 sy,  0.0 ni, 43.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu17 : 41.6 us,  0.7 sy,  0.0 ni, 57.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu18 : 44.5 us,  0.0 sy,  0.0 ni, 55.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu19 : 38.6 us,  0.3 sy,  0.0 ni, 61.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu20 : 62.9 us,  0.0 sy,  0.0 ni, 37.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu21 : 48.7 us,  2.6 sy,  0.0 ni, 48.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu22 : 44.4 us,  0.7 sy,  0.0 ni, 55.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu23 : 38.9 us,  0.0 sy,  0.0 ni, 61.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu24 : 67.2 us,  0.0 sy,  0.0 ni, 32.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu25 : 73.8 us,  1.0 sy,  0.0 ni, 25.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu26 : 63.9 us,  0.0 sy,  0.0 ni, 36.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu27 : 63.6 us,  1.3 sy,  0.0 ni, 35.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu28 : 62.1 us,  0.0 sy,  0.0 ni, 37.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu29 : 61.3 us,  1.0 sy,  0.0 ni, 37.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu30 : 61.6 us,  0.0 sy,  0.0 ni, 38.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu31 : 63.2 us,  1.0 sy,  0.0 ni, 35.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
```

### topの比較

- 最適化前
    - `load average: 10.02, 5.47, 2.28`
- 最適化後
    - `load average: 11.43, 10.96, 10.31`

これが関係するのだろうか?
最適化前の場合、真ん中と右の数値が左の数値の半分程度以下になる傾向がある。
最適化だとほぼ同じ値になり、計算資源の利用効率が上がっているようにも思われる。

- [load averageを見てシステムの負荷を確認する](https://qiita.com/k0kubun/items/8065f5cf2da7605c8043)
    - by @k0kubun 様
        - 情報感謝です
   
> load averageは、左から、直近1分, 5分, 15分間で計測したものを表している。

## 最適化前後のwall time

作成されたファイルのタイムスタンプからの計算時間概算。

- 最適化前 > 32スレッド使用
    - 28.8時間
- 最適化後 > 4スレッド使用の7並列
    - 4.6時間

7倍くらい高速化した。

## まとめ

並列計算をする場合、むやみにスレッド数を増やすのでなく、スレッド数4程度で並列実行する方が計算は早くなる。
14年くらい前からそういう計算を時々して良くなる経験をしている。

今回も同様の方針で実施したところ、成功した。

## 関連

下記の方法を使って、並列実行する時の処理対象パラメータファイルの選択をするように実装した。

- [bash > fileIO > 並列化 > ls + awk > 入力ファイルをINTVLとINDX指定で分割する > コマンド | bashスクリプト v0.1, v0.2 | brace expansionによる失敗](https://qiita.com/7of9/items/0e03dfba17ce77bc9f6d)