もどる
fire1.gif 遅すぎた計算 00/03/23
回転もうまくいき、実時間問題もなんとかのりきった。目標としていた「多関節物体」も どうやらうまくいきそうだ。しかし.....
ここでさらに、新たな問題が。 タイトルのとおり、計算が遅い。はっきりいって遅すぎます。 確かに、遅くなる、というのはある程度わかっていたつもりでしたが、ここまでとは....!!

(火の玉オブジェクト50個くらい)+(ExtremeShootersの自機 三つ)程度でここまで 重い原因は何か? おそらく一番重いと思われるところは、「物体座標系 → 絶対座標系」の計算部分です。 コードを持ってくると・・・・


procedure TMover.Transform;
var temp:TVector;
    mat:TMatrix;
    fp:TMover;
begin

  if Self = Movers.SceneFrame then exit;
  if SceneFrame = nil         then exit;

  temp:=ZeroVector;

  //(軸ベクトル)×(位置ベクトル)+ (座標軸の位置ベクトル)
  fp:=Self;
  mat:=MatrixRotateZ(trunc(fp.Coord.Z));
  IncVector(temp,TransformVector(fp.FMoveMent,mat));
  IncVector(temp,FPos);

  //親フレームがNULLになるまでループ
  while fp.SceneFrame <> nil do begin
        fp:=fp.SceneFrame;
        mat:=MatrixRotateZ(trunc(fp.Coord.Z));
        IncVector(temp,TransformVector(fp.FMoveMent,mat));
        temp:=TransformVector(temp,mat);
        IncVector(temp,fp.FPos);
  end;

  //絶対座標をセット
  FGPos:=temp;

end;
この赤で示した部分でしょうね、時間かかってるのは。 ベクトルと行列の合成部分がwhileループ一度につきなんと2回も!! 考えるだけでも恐ろしいですね。ちなみに、このベクトルと行列の合成には 乗算が9回もでてきます。 つまり、浮動小数点の乗算が18回!! これは遅くないほうがおかしいです。しかも、これはまだZ軸回転しか計算していない場合です。 もし、X,Y軸回転も計算しちゃったら.....うーむ。 んじゃ、どうやって高速化を図るかを考えてみます。

  • 固定小数点を使う
  • 回転角度が0のときは行列とベクトルの合成が無意味なので計算を省く
  • というか、FMovementとmatの合成は無意味(使ってない)
  • whileループの中で足しこまれるベクトルをどうにかして先に求めておいて使いまわす
  • DirectX7の新機能のT&L部分の「T」を利用する(Transform = 座標変換)
  • 計算で出る遅れを画像処理の高速化でカバー
うーん、脳が弱ってるなぁ(^^;)一部むちゃくちゃなのがありますね(特に後半)。

まず、一つ目。固定小数点は「もどき」みたいなのをやったことがありますが、その適当なやつでも 浮動少数よりは速かったと思います。もっとちゃんとすればかなりよくなるでしょう。

二つ目。回転角度が0、っていいきってますが、 合成結果が容易に想像できるものはこっちで簡単に処理する、ってなことがいいたいわけです。 実際回転角度0のときは、「1」をかけるだけなので、計算時間の無駄なんです。

三つ目。これはプログラムをごちゃごちゃいじくってるときに出てきた「ゴミ」でしょう。無駄。

四つ目。これができるとかなり速くなりそう。しかし実装は結構面倒くさそう。 まず、「子を多く持つフレーム(ていうか親を持たない)」の順番でオブジェクトをソートして、 位置ベクトルを算出して、自分のIDといっしょにテーブルにいれます。 んで、使うときはテーブルから親のIDを参照して引っ張ってくる、と。 これは、同じ親を持つオブジェクトが多ければ多いほど効果が見込めます。 でも、親を持つオブジェクトが少ないとあまり効果は見込めません。 しかし、いつもやってれば遅くなることはないでしょう。

五つ目。結局は計算をできることならハードウェアに任せよう、ってことです。 しかしこれにはハードウェアがまだ全然そろってきてない、という問題があります。 とはいうものの、僕みたいな高速化のシロートが書いたプログラムよりも、 HELの方が速いかな、という考えです。
しかし、手元にDirectX7のパスカル用ヘッダがないという厳しい現実が待ち受けているので、 あまり現実的ではありません。

六つ目。これは明らかに無理ですね(^^;)

と、いろいろ列挙してみました。が、現実問題としては僕的にかなり 実装が困難なものばかり。現実は厳しいのです(←って誰にいってんの?)。 それにしても、もういまどきは「ソフトウェアで計算」なんて流行んないのかなー。 ・・・いや、ハードに頼ってばかりでは「そのハードにある機能」しか使えないじゃないか!! ソフトウェア計算なら、自分の思いついたものをどんなものでも形にできるじゃないか!! 今は、そう信じて突き進むしかない!!

次へ進む
※高速化
「速くしたいならループを見直せ」とはよくいったもの。 ループ部分には魔物が住んでいるのです。






もどる