くまりゅう日記

もっと過去の日記
[.NET | BeOS | Blender | COLLADA | fossil | mono | monotone | NPR | OpenGL | PeerCastStation | Riko | Ruby | Silverlight | TRPG | XNA | ゲーム | ゲーム作り | ]

2014-02-10

日記

大雪だった。 まあそんなにつもらんだろうと思ったら、朝方見たら既に道路が白くなっており、寒いので二度寝して起きたらもう一面真っ白だった。 しかも夜まで一日中降ってたし。日曜にはやたらとあったかくなって融けてきてたけど、しばらくは残りそうだ。

土日だったから良かったものの平日だったら大変なことになってたね。平日だったら意気揚々と休んで阿鼻叫喚な状況を見てニヤニヤできてただろうに残念だ。

Intuos3はWindows8非対応……か?

PC組み換えてWindows8.1にしてから、そういやタブレット(って紛らわしいな。ペンタブレットのことだ)のドライバ入れてないと気付いたので落としにいったら。

Intuos3のドライバを落とそうとするとOS選択画面が出るがWindows8が選択肢に出てこない。……いや、WacomがWindows8対応してないとかありえないだろ。と、Windows8対応状況を見に行くとIntuos3はWindows7までの対応だと。あわわ。

ペンタブなんて世代毎でそんなに通信仕様が変わってるわけでもないだろうし、Windows7から8なんてそんなに変わらんし(と思ったがペンやタッチ周りは結構変わったりしてるのだろうか?)、いつまでも動くもんだと思ってたがダメなのか! まあいいつまでもサポートできませんよとか、そろそろ新しいの買ってもらえないと困りますよとかそんな話なのかもしれないが、HW的にはまだまだ普通に動くのにもったいないなぁ……。 そんなにしょちゅうは使ってないからなおさらだ。

ワイヤレスのやつとかタッチもできるやつがちょっと欲しいかもと思ってたから買い時なのかもしれないが、調べてみるとそれなりの出費になるなぁ。 ペンタブ無いと困るかというとすぐ困るわけではないので、値段調べたりしてしばらく考えるか。

その後ちょっと気になってIntuos3のWindows7用のドライバが使えないか試そうとしたら、Windows Vista/7用ドライバのリリースノートにWindows 8.1対応しましたという謎の文言が入っていて、インスコしたら普通に使えた。Windows 8.1対応したという新機能が入るWindows Vista/7用のドライバとはいったい。

[Ruby] IronRubyが遅いと思ったら

IronRubyでゲーム書いるんですけど(全然進んでない)、どうもやたらと遅いんですよね……。

どこが重いのか計ってみようとしたら、そもそも時間計測が遅い。なんでだよ!

時間計測はこんなコードでタイムスタンプを取ってそれの差分を計算して行ってるわけですが……

@@freq = 1000000.0/System::Diagnostics::Stopwatch.frequency
def timestamp
  System::Diagnostics::Stopwatch.get_timestamp*@@freq
end

こいつが既に遅い。System::Dignostics::Stopwatchは.NETのクラスね。普通にTime.now使わないのは少なくともWindowsだとよくても1ms、普通は10ms単位くらいの精度しか出ないためです。

ぱっと見はおかしいところないのでしばらく悩んでいたんだが、System::Dignostics::Stopwatchが遅いことに気付いた。SystemSystem::DiagnosticsはRubyのモジュールではなく.NETの名前空間だ。IronRubyはそれをあたかもRubyのモジュールのように見せかけてはいるがあくまでも別物で、System::Dignostics::Stopwatchと書くと毎度延々と名前空間やらクラスやらを探しにいっていたようだ。そりゃおせぇ。まあ実装までは見てないから毎度じゃないかもしれないが、キャッシュされてたとしてもあんまり効いてもなかったようだ。

じゃあということで

Stopwatch = System::Diagnostics::Stopwatch
@@freq = 1000000.0/Stopwatch.frequency
def timestamp
  Stopwatch.get_timestamp*@@freq
end

としたらだいぶ速くなった。よかったよかった。

しかしまだちょっと時間食ってる気がして謎だなぁ。なんとなく気になるところはクラス変数だろうか。 クラス変数が実は遅いんじゃないかという気もしたので、変数のアクセス(読み出し)速度を調べてみた。するとなんと驚きの結果が!

IronRubyでの変数読み出し速度比較。速い順
ローカル変数>Structメンバ>>インスタンス変数≒Hashエントリ>>クラス変数

こんな結果でした(IronRuby 1.1.3)。計測したスクリプトが諸事情により無くなってしまったので数字はないです。 ローカル変数が速いのはわかるけどStructメンバの異常な速さは何これ。ていうかインスタンス変数遅すぎじゃない?

JRuby 1.7.4くらいでも計ってみました。ちょっと古い

JRubyでの変数読み出し速度比較。速い順
ローカル変数>インスタンス変数>>Hashエントリ>>Structメンバ>>クラス変数

具体的な数字が書けてないけど、IronRubyはなんだったんかという程インスタンス変数めちゃくちゃ速い。 一方Structメンバがなんでこんなにっていう程遅くなってる。どこに遅くなる要素があるんだ?

IronRubyのインスタンス変数の遅さとStructメンバの異常な速度をソースを見て調べてみると、まずインスタンス変数は順当にDictionary<string,object>で実装されてた。順当だけどもうちょっと最適化の余地はありそうですね。キーがstringって……。

ついでにHashも調べてみるとこいつはもうまんまDictionary<object,object>だった。順当ですな。 インスタンス変数とHashの速度がだいたい同じなのはこういうことか。Dictionaryは思ったより遅いんだなぁ。

Structの実装を調べてみると、こいつは中身がobjectの配列だった。アクセス用のメソッドもクラス作ったときに式木で定義されるのでアクセスも速そう。 作った時点でメンバが確定するからこういう最適化が出来るんだね。

クラス変数が遅い理由は調べるの大変そうだったのでやってないんだけど、まあそんなに使う物じゃないのでループ内で使わないよう気をつければよかろう。

CRubyでも計りたかったんだけど、Time.nowでは精度が出ないのでWindowsのパフォーマンスカウンタ相当の物を取るのに簡単な方法が思い付かなかったので保留した。ちなみにJRubyではjava.lang.System.nano_timeを使いました。

以上の結果から、タイムスタンプの取得は

def initialize
  @stopwatch = System::Diagnostics::Stopwatch.new
  @stopwatch.start
end

def timestamp
  @stopwatch.elapsed.ticks / 10
end

にしました。

これでやっとどこが重いのか調べられる……って思ったが、文字描画が重いんじゃー! 画面にパフォーマンスカウンタを表示させようにも表示が重いんだよ。

文字描画が重いのはまあ分かってたんだけど、ちゃんと調べてみると実際描画する前のフォーマット時点で既に重い。 テキストを描画しようとすると、一文字毎に分解して文字情報取ってきてレイアウトするって作業をするわけだ。 レイアウトした情報はその場で描画しないで保持しておく。これだけの作業なのに300文字で9msもかかってることが発覚した。 文字毎に処理するって量多いけどこれ以上削減できないし、300文字ってそこまで多くもないだろ。 9msって短くも見えるけど、60fpsのゲームだったら1フレームは16msしかないわけで、文字のレイアウトだけで半分以上持ってかれたらゲームどころではない。

見てたら文字毎のループ内でインスタンス変数が結構使われてますな。 これをStructにまとめたら速くなるのかなーとやってみたら速くなった。3msくらい。 実行時間66%削減!速い!って300文字のレイアウトに3msかー。

よく考えたらStructにする必要なくてループの外でインスタンス変数をローカル変数におとせばいいだけじゃん。 それをやって他にループ内でのメソッド呼び出しなんかもできるだけローカル変数にキャッシュしてループ外に出したら1ms弱くらいまで削減できた。 やったー。

300文字のレイアウトだけに1msってふざけてんのかと言う程長いけど、たぶん許容範囲なので今のところは気にしないことにしよう。

次は描画側をなんとかしないとなぁ。たぶんこっちもインスタンス変数減らしたりすればちょっと速くはなるけど、そもそも一文字毎にDrawCall発行しちゃってるあたりがやばいからなぁ。

[fossil] fossil 1.28

全部入り(?)バージョン管理ソフトであるfossilの1.28がちょっと前に出てたのに気付いたのでまた変更点を訳しておきます。

http://www.fossil-scm.org/download.html

2014-01-27 17:33:44 バージョン1.28です。このリリースでの主な変更点は以下の通り:

  • /reportsでイベント種別による絞り込みができるよう強化しました。 リポジトリをクローンした時に、URLで指定したユーザ名(があれば)をローカルな管理者ユーザ名のデフォルト値として使うようにしました。
  • SSHトランスポートの仕組みを改善し、リモート側で実行ファイル”fossil”のインスタンスを一つ立ち上げるようになりました。リモート側でシェルは必要なくなります。fossilのバイナリが標準的な場所に無い場合は”ssh:”なURIに”?fossil=/path/to/fossil”といったクエリパラメータを追加する必要があります。
  • “fossil blame”コマンドを追加しました。これは”fossil annotate”と同じような動作をしますが、出力に誰が変更したかが追加され、行番号は逆に出力されなくなっています。
  • Admin/Configuration以下に”Tarball and ZIP-archive Prefix”(TarballとZIPアーカイブの前につける名前)の設定パラメータを追加しました。
  • REQUEST_URIを渡さないウェブサーバでもCGI処理が動くように修正しました。
  • “fossil clean”コマンドに--dirsonly, --emptydirs, --allckoutsの各オプションを追加しました。
  • でかい対象への”fossil blame”や”fossil annotate”コマンド実行が10倍も速くなりました。
  • “fossil timeline”と”fossil finfo”の各コマンドに-W|--widthオプションと--offsetオプションを追加しました。
  • “fossil timeline”への-n|--limitオプションが他のコマンドと同様にエントリの数を指定するよう変更されました。タイムライン関係の機能は上限に達すると出力の末尾に”— ?? limit (??) reached —“を出力するようになりました。上限を無しにしたい場合は”-n 0”を指定してください。
  • FossilのURLに埋め込まええたパスワードの扱いを修正しました。
  • fossil cloneコマンドに--onceオプションを追加しました。クローン時に指定したURLやパスワードを保存しないようにします。
  • fossil uiが開いているリポジトリの”default user”を見るように変更しました。
  • “hidden”タグがついているチェックインはタイムラインページ上に表示されないようになりました。
  • /ci_editページでチェックイン毎に”hidden”タグを追加できるようにしました。
  • TH1スクリプトを使ったHTTP経由でのコミット・チケット変更通知の可能性を発展させました。(訳注:訳せなかった……Advanced possibilities for commit and ticket change notifications over http using TH1 scripting.ですって)
  • “fossil commit”コマンドに--sha1sumオプションと--integrateオプションを追加しました。
  • “fossil all”コマンドに”clean”と”extra”のサブコマンドを追加しました。
  • “fossil clean”に--whatifオプションを追加しました。これは”–dry-run”と同じ動作をしますが、”fossil all”の--dry-runと名前が衝突しないために追加されました。
  • タイムラインの日時表示を”YYMMDD HH:MM”形式にする設定オプションを追加しました。
  • “stats”ページに管理者が現在のリポジトリスキーマを見ることができるオプションを追加しました。
  • “/vdiff”ページでさらに多くの差分表示オプションを選べるように強化しました。
  • “/dir”ページの代替として”/tree”ページを追加し、これをファイルリスト表示のデフォルトとなるようにしました。
  • クライアントが対応している場合はHTTPレスポンスをgzip圧縮するようにしました。

ファイル一覧はツリー表示がデフォルトになったというので喜んでみたんですけどなってるようには見えませんね……。 訳し間違えたかと思ったけどそうでもなさそうなんだが?

タイムラインの上限表示あたりが細々と変更入ってるのはうれしい。上限に達したのでやめましたという表示がないとわからんのよね。まあ普段Web UI使ってるんで関係ないですけども。


ページのトップへ | トップ «前の日記(2014-02-01) 最新 次の日記(2014-02-24)» | 編集 | kumaryu.net by kumaryu