バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
前回、Python+FMU+tkinterによるHILSもどきの負荷に対して、
描画を一時的に止めることで精度を引き上げられることがわかった。
これはこれでOKなのだが、
やはり描画もキープしつつ負荷が下げられないかも検討したい。
登場人物
博識フクロウのフクさん
![指差しフクロウ](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/指差しフクロウ.png)
イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん
![技術者太郎](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/技術者01アップ.png)
イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
描画をしつつ負荷を下げられないか?
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/「技術者a」20アップ.png)
前回までの話だと・・・。
- 描画してると負荷が上がってFMUへの入力が一時的に止まる
- 負荷を上げたければ描画を止める
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/技術者02アップ.png)
って感じだったと思うのだけど、
もう一ついい方法を思いついたぞ!
![フクさん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/はてなフクロウ.png)
ほう?
とりあえず聞こうか?
太郎くんの考えた負荷低下案
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/「技術者a」08アップ.png)
スレッドを使う!
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/技術者01アップ.png)
ちょっとググったけどPythonもスレッドが使えるみたいだから
FMUとmatplotlibの描画を別のスレッドにしてしまえば、
描画で処理時間持ってかれても大丈夫なんじゃない?
![フクさん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/考え中フクロウ.png)
うーん、残念だがそれはうまく行かないかな?
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/「技術者a」10アップ.png)
え゛
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/「技術者a」09アップ.png)
なんで?!
こういうのって結構マルチスレッドで解決すること多くない?!
![フクさん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/考え中フクロウ.png)
まぁ確かにマルチスレッドで解決するパターンではあるのだが・・・。
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/「技術者a」20アップ.png)
なんか割と明確な理由がありそうだな・・・。
スレッドを使っても負荷が下がらないと思われる理由
![フクさん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/指差しフクロウ.png)
Pythonに限らずインタプリタ系言語共通の問題なんだと思うんだけど、
GIL(Global Interpreter Lock)の仕様の影響でさほど並行性確保できないんだよね。
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/「技術者a」13アップ.png)
GIL?
![フクさん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/お休みフクロウ.png)
Wikipediaから引用しよう。
グローバルインタプリタロック(英: Global Interpreter Lock, GIL)とは、プログラミング言語のインタプリタのスレッドによって保持されるスレッドセーフでないコードを、他のスレッドと共有してしまうことを防ぐための排他 ロックである。インタプリタのひとつのプロセスごとに必ずひとつの GIL が存在する。プログラミング言語においてグローバルインタプリタロックを採用した場合、複数のスレッドを持つインタプリタプロセスの並行性を制限してしまう。プロセスをマルチプロセッサのマシンで実行させた場合、ほとんどあるいはまったく速度の向上が見られない。
Wkipediaより(https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%97%E3%83%AA%E3%82%BF%E3%83%AD%E3%83%83%E3%82%AF)
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/「技術者a」20アップ.png)
うーん、つまりコンパイル型の言語だとCPU命令単位に近いレベルでコンテキストの切り替えはできるけど、インタプリタ型言語だと言語レベルの命令単位でしか切替ができないってこと?
![フクさん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/まるフクロウ.png)
その認識でOKだ。
![フクさん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/お休みフクロウ.png)
というわけで、今回の負荷となっている描画処理なのだが、Python的には1命令なんだよね。
その命令が終わるまではどっちみち別スレッドも実行されないんで、
負荷は分散されず、ほぼ結果はかわらないだろう。
![太郎くん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/「技術者a」10アップ.png)
まじかー。
まとめ
![フクさん](https://www.simulationroom999.com/blog/wp-content/uploads/2020/05/指差しフクロウ.png)
まとめだよ。
- 描画を止める以外で負荷低減方法を検討してみた。
- スレッドの利用案が出たが以下の理由で不可。
- GIL(Global Interpreter Lock)仕様の影響で期待するスレッドのコンテキストスイッチにならない。
- よって、負荷はほぼ減らない。
- 下手したら増える可能性もある。
- というわけで対策としては見送り。
バックナンバーはこちら。
コメント