2011-01-26 27 views
1

私はDelphi 2007を使用していて、いくつかのプレゼンテーションソフトウェアで作業しています。私が取り組んでいる現在のモジュールは、ビデオのトランジションフィルタです。私が使用しているトランジションコード(TPicShowのPSEffectsユニット)には、フレームのサイズとトランジションの進行状況に基づいてX値とY値が必要です。ここでは、コードMulDivは、既知の値を保存して他のコードで数学を行うよりも効率が悪くなる可能性があります

Type 
TPercent = 0..100; 
var 
ATo : TBitmap; // 
Prog : Integer; //Progress of the transition 

     if ATo.Width >= ATo.Height then 
    begin 
     X := MulDiv(ATo.Width, Prog, High(TPercent)); 
     Y := MulDiv(X, ATo.Height, ATo.Width); 
    end 
    else 
    begin 
     Y := MulDiv(ATo.Height, Prog, High(TPercent)); 
     X := MulDiv(Y, ATo.Width, ATo.Height); 
    end; 

は、私はこれを最適化しようとしていると私は(ATO変化の大きさになるまで)一定になる計算を保存し、2つの分割の計算に各フレームを削除することができることを見ました。

だから、

{All of these are calculated when the dimensions of ATo Change} 
WDP : real; // width divided by High(TPercent) 
HDW : real; // Height divided by width 
HDP : real; // Height divided by High(TPercent) 
WDH : real; // Width divided by Height 

    if ATo.Width >= ATo.Height then 
    begin 
     X := Trunc(WDP * Prog); 
     Y := Trunc(HDW * X); 
    end 
    else 
    begin 
     Y := Trunc(HDP * Prog); 
     X := Trunc(WDH * Y); 
    end; 

ようなものになるだろうそれは良い音が、私は必ずカントMulDivの実際のコードを持っていません。それは単に(非常に単純化された)

MulDiv(a,b,c : Integer) 
begin 
    Round((A*B)/C); 
end 

を行う場合、私はその後、私はありません(私はそれがかもしれないものをいただきたいもの)MulDiv機能を最適化すると非常にクールなものを行うがあれば、私の変更は、より効率的になります知っています私の変更が私に何かをネットするかどうか確かめてください。

私の変更はより効率的でしょうか?

編集:私はまだこれを実装していない、私はただの観念を楽しんでいる。

+2

「Y」の値は実際には「X」に依存しないことに注意してください。あなたは 'MulDiv(X、ATo.Height、ATo.Width)'として 'Y'を計算しますが、' MulDiv(ATo.Height、Prog、100) 'として直接計算することができます。一度これを行うと、幅が高さよりも大きいかどうかに関係なく、 'X'と' Y'の計算が*同一*であることがわかります。 –

+0

@Rob:ありがとうございます – Tim

答えて

2

整数演算を使用して実装されたMulDivの呼び出しが非効率的で、パフォーマンスの問題の原因となった場合、私は非常に驚くでしょう。あなたはあなたのプログラムをタイムリーにしましたか?プロファイラを使用してアプリのホットスポットを特定しましたか?

個人的には、整数から倍精度浮動小数点演算への切り替えがパフォーマンスを向上させる可能性は低いと思います。

いずれにしても、私が推測するのは、表示されたコードの後に​​、XYを使用し、この小さなスニペットよりも多くのCPUを消費する他のコードがあると思います。あなたはおそらくXYを計算しないで、それらを捨てるでしょう:それらで何をしますか?

EDIT:MulDivのワインの実装は、おそらくWindowsの1に非常に近く、かつその根性がそうである:他の人が述べてきたように

if (((nMultiplicand < 0) && (nMultiplier < 0)) || 
    ((nMultiplicand >= 0) && (nMultiplier >= 0))) 
    ret = (((LONGLONG)nMultiplicand * nMultiplier) + (nDivisor/2))/nDivisor; 
else 
    ret = (((LONGLONG)nMultiplicand * nMultiplier) - (nDivisor/2))/nDivisor; 
+0

私はこの状況が私のパフォーマンスの問題の唯一の原因であるとは思わないが、私はこの小さなスニペットを改善できるかどうかを知りたいと思った。 XとYについては、Kambiz Khojastehが作ったTPicShowに属するPSeffectユニットの関数にそれらを渡す以外に何もしません。私は自分のコードですべてを最適化したかったので、あまりにも多くのコードを見ていませんでした。しかし、見やすい一見では、XとYを取り入れている間に少なくとも少数の移行関数がそれらを使用していないように見えるので、そこで改善の余地がある。 – Tim

+2

@Tim私の主なポイントは、この小さなスニペットコードを改善することは、ボトルネックではない場合には役に立ちません。 TPicShowのコードが何か重要なことを行っている場合、このスニペットを最適にすることで、いつでもあなたを節約することはできません。あなたが最適化する前に、何が遅いかを理解する必要があります。間違ったことを最適化すると、実際には悪化します。非常に一般的には、高度に最適化されたコードは理解しにくく、メンテナンスの問題になるからです。通常、早すぎる最適化の最終結果は、これまで以上に高速ではなく、正しく動作しないプログラムです。最後のコメントDavidのために –

+0

+1。それは私には分かりましたし、いくつかのコード最適化資料を読んで私に多くの意味があります。 – Tim

3

MulDivの実際のコードはWinAPI関数なので、このコードは見つかりません。私はWinAPI自体に多用されているので、たぶんいくつかの関数呼び出しではなく、おそらくかなり最適化されたアセンブラコードだと思われます。

変更がより効率的であるかどうかを判断するには、両方の方法でコードをプロファイルし、どちらが速いかを確認するしかありません。 Delphi XEを使用している場合は、付属のAQTimeを使用できます。

ところで、最適化などのことについて話しているとき、コンパイラの変更によって答えが変わる可能性があるため、実際に使用しているDelphiのバージョンを示すことは非常に便利です。

+0

ありがとうございました。最初の段落でどのバージョンのDelphiを使用していたのか説明しましたが、今もタグに追加しました。 – Tim

+0

仮想メモリを式に含めることなく「高速」になるコードの一部は、純粋にCPUにバインドされているのではなく、単にリソースにバインドされます。つまり、あなたのアイデアをサポートするためのプロファイラデータがあるまでは、アプリの速度が遅く、膨大なRAMが必要になるというKenの賢明な声明です。 –

1

、あなたはプロファイラを探している必要がありホットスポットを特定する。

あなたがそれらを特定したら、あなたの現在のコードよりも速いものをマルチメディアアプリケーションで見つけたら、SIMD機械語の命令について学ぶ必要があり、手で最適化されたアセンブラコードより速い結果を得ることができます。

浮動小数点型を使用して自分自身でPascalに書き込むことは、パフォーマンスが向上する可能性はほとんどありません。中間結果をキャッシュすると、メモリ使用量が指数関数的に増加し、速度の中程度の向上のみで、VMのページング(スラッシング)が発生する可能性のあるシステムでは実際に速度が低下する可能性があります。

関連する問題