バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
前回、Python+FMU+tkinterによるHILSもどきの負荷に対して、
描画を一時的に止めることで精度を引き上げられることがわかった。
これはこれでOKなのだが、
やはり描画もキープしつつ負荷が下げられないかも検討したい。
登場人物
博識フクロウのフクさん
イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん
イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
描画をしつつ負荷を下げられないか?
前回までの話だと・・・。
- 描画してると負荷が上がってFMUへの入力が一時的に止まる
- 負荷を上げたければ描画を止める
って感じだったと思うのだけど、
もう一ついい方法を思いついたぞ!
ほう?
とりあえず聞こうか?
太郎くんの考えた負荷低下案
スレッドを使う!
ちょっとググったけどPythonもスレッドが使えるみたいだから
FMUとmatplotlibの描画を別のスレッドにしてしまえば、
描画で処理時間持ってかれても大丈夫なんじゃない?
うーん、残念だがそれはうまく行かないかな?
え゛
なんで?!
こういうのって結構マルチスレッドで解決すること多くない?!
まぁ確かにマルチスレッドで解決するパターンではあるのだが・・・。
なんか割と明確な理由がありそうだな・・・。
スレッドを使っても負荷が下がらないと思われる理由
Pythonに限らずインタプリタ系言語共通の問題なんだと思うんだけど、
GIL(Global Interpreter Lock)の仕様の影響でさほど並行性確保できないんだよね。
GIL?
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)
うーん、つまりコンパイル型の言語だとCPU命令単位に近いレベルでコンテキストの切り替えはできるけど、インタプリタ型言語だと言語レベルの命令単位でしか切替ができないってこと?
その認識でOKだ。
というわけで、今回の負荷となっている描画処理なのだが、Python的には1命令なんだよね。
その命令が終わるまではどっちみち別スレッドも実行されないんで、
負荷は分散されず、ほぼ結果はかわらないだろう。
まじかー。
まとめ
まとめだよ。
- 描画を止める以外で負荷低減方法を検討してみた。
- スレッドの利用案が出たが以下の理由で不可。
- GIL(Global Interpreter Lock)仕様の影響で期待するスレッドのコンテキストスイッチにならない。
- よって、負荷はほぼ減らない。
- 下手したら増える可能性もある。
- というわけで対策としては見送り。
バックナンバーはこちら。
コメント