TESV Acceleration Layer – cont’d

昨日見つけた TESV Acceleration Layer を入れて play してみたところ、確かに若干 performance が向上したかな、と言う感じだ。Rendering performance そのものには影響を及ぼさないけれど、TESV.exe 本体の code execution はかなり smooth になっている感じ。後は hook しながら見ていると大量のただ return 0 するだけの function calls が減っているので execution speed に関しては確かに向上していると言えるだろう。

ただ、どうも cell header を書き換えてしまったときの様な script が正常に実行されない系統の問題が目に付きやすくなった感じ。

Script が正常に実行されない、あるいは delay する問題というのは 1.3.7 からあったんだけど、この plugin を使うとより目に付く感じだ。

Plugin が行っているのは、build/compile 時に compiler に /O2 (optimize) の flag を渡して生成されるであろう “最適化” されたに違いない code と実際の memory 上に展開された code をすげ替える、というそれなりに単純な動作なのでやはり Engine 自体が compile-time optimization を実施すると挙動がおかしくなる問題があるんだろうな、と言うところだ。

恐らく最適化したときの挙動が unexpected だったので Bethesda は最適化を行わない build を release しているのだろう… 時間と労力をかけて調べれば突き止められる問題だけれど、全ての compile 済み code の white-box test を行って検証するのは、どれくらい時間がかかるか気が遠くなるような話だ。

というわけで、forum の現行 thread を見に行くと、同じような report が複数上がっている。一番再現性が高いのは、

  • 新規に game を開始
  • Hadvor か Ralof か、どちらに着いていくかの分岐で Ralof に着いて Keep に

後は装備をして、Imperial Soldier と Captain がやってくるところまで進むと、Ralof と Imperials と両者開いた gate を挟んで睨み合い状態になる。

本来ならここで Ralof が身を隠して、Imperials が Gate を開けたところで襲い掛かるという進行なんだけれど、Ralof はただ立ったまま、Imperials も Gate を開けてただ立ったままの状態になる。ここで、player が Imperials に近づくと Ralof が動き出して Imperials に襲い掛かるけれど Imperials は反撃せずにただ殺されると言う状況に。

こういう微妙な script の実行漏れ、あるいは遅延的な状況は 1.3.7 以降たまに目にしてがっくりするんだけれど、この plugin を利用した場合、この場面では常に 100% 再現可能だ。ちなみに plugin を削除すると何の問題も起きない。(Plugins folder の中で rename しても SKSE はそこに存在する DLL はどんなファイル名であろうと load するので、削除か、全く関係ないところに移動する必要がある)

というわけで、今のところそれほど performance 的には困っているわけではないので当分使わないことにしよう、というところ。

P.S.

Helgen での新規 game の問題は test_bit_30 に対する replace が問題の直接の原因のようだ。基本的には code.inc からこれを取り除いて table.inc からの参照を削除、その上で compile しなおしてみたところ正常に進行した。

ただ、他の test_bit_xx 関連の部分も微妙に replace が必要かどうか判断がつかない部分があるので、時間をかけて調べないと fix は難しい感じ 😦

P.P.S.

Original author によれば setz と setnz が間違えている、と言うことなので、Pathes.replace.test_bit_30 を以下のとおり修正して compile しなおせば問題なく使える。

; v1.3.10.0: $0051E340
@@: Patches.replace.test_bit_30:
test dword [ecx+152], $20000000
 setz al
retn
.size = $ – @b

setz (set byte if zero) / setnz (set byte if not zero) を間違えると (多分 typo じゃないだろうか) 本来 1 を返すべきところで 0 を返してしまうことになる。

Fixed version available on Skyrim Nexus

 

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中