Exerbで変換した実行ファイルのThread切り替えオーバヘッド(?)問題

背景と目的

  • namareco.rbに比べてnamarecowin.exeがやたらと重いようなので原因調査してみた
    • namarecowin.exeは録画中CPUをほぼ一つ食い尽くすようだ
    • namarecowin.exeのRTMPパケット処理ループを空にして実験してみたところ通常時と同様の負荷が観測された
      • そこで問題を単純化し以下の実験を行ってみた

評価環境

  • 実行環境
  • 評価に使ったプログラム(評価プログラム)
#!/usr/bin/ruby
require 'thread'
require 'date'

threads = []
threads.push(Thread.new{i = 0; loop do; puts DateTime.now.to_s + ' ' + i.to_s if i % 1000 == 0; i += 1; sleep 0.005; end})
threads.each{|t|
  t.join
}
    • sleepさせている時間はRuby版では負荷が0となりWin版では負荷が現れる値を選択

評価結果

2010-05-21T21:06:16+09:00 0
2010-05-21T21:06:32+09:00 1000
2010-05-21T21:06:47+09:00 2000
2010-05-21T21:07:03+09:00 3000
    • 1000回転するのに大体16秒かかっている
    • CPU負荷はほぼ0%
  • Win版
2010-05-21T21:04:30+09:00 0
2010-05-21T21:05:01+09:00 1000
2010-05-21T21:05:33+09:00 2000
2010-05-21T21:06:04+09:00 3000
    • 1000回転するのに大体31秒かかっている
    • CPU負荷はおよそ25%

比較実験

  • 比較に使ったプログラム(比較プログラム)
#!/usr/bin/ruby
require 'date'

i = 0; loop do; puts DateTime.now.to_s + ' ' + i.to_s if i % 1000 == 0; i += 1; sleep 0.005; end
    • Threadを起動せずループをmainスレッドでまわしている
  • Ruby版結果
2010-05-21T21:16:31+09:00 0
2010-05-21T21:16:47+09:00 1000
2010-05-21T21:17:03+09:00 2000
2010-05-21T21:17:18+09:00 3000
  • Win版結果
2010-05-21T21:17:27+09:00 0
2010-05-21T21:17:42+09:00 1000
2010-05-21T21:17:58+09:00 2000
2010-05-21T21:18:13+09:00 3000
  • メインスレッドでループをまわした場合はRuby版Win版ともほぼ同様の結果が得られた
    • 1000回転するのに大体16秒かかっている
    • CPU負荷はほぼ0%
    • これらは評価プログラムのRuby版とほぼ同様の結果
  • Exerbで変換した場合Thread中でループを回すと一定の負荷がかかるようだ
    • これはつまりThread切り替えのオーバヘッドか?

まとめ

  • namarecowin.exeの高負荷はIO周りの記述ミスまたは不具合かと考えたが上記の実験よりThread周りの可能性が出てきた
    • Thread切り替えのオーバヘッドか?
  • Exerbは実行に必要なインタプリタ一式+ソースコードを一まとめにしているだけではない?
  • いずれにしろ改善策は今のところ見つからず

ToDo

  • この件に関するドキュメントの検索あるいはソースを見てみる?
  • どこかで質問してみる?