2017-02-16 4 views
0

2つの数値を乗算して最終結果をシフトするサブルーチンを実行する必要があります。インプレース乗算サブルーチン - ポインタまたは値を渡す?

より適切サブルーチンである:コードは、DSPプロセッサ上で実行されるので、速度とサイズの両方でなければならない

void mul_inplace_both_pointers(q23* inout, q23* in) 
{ 
    *inout = (*inout * *in); 
    *inout = *inout << 8; 
} 

又は

void mul_inplace_one_pointer(q23* inout, q23 in) 
{ 
    *inout = (*inout * in); 
    *inout = *inout << 8; 
} 

又は

q23 mul_no_pointers(q23 in1, q23 in2) 
{ 
    q23 out; 
    out = in1 * in2; 
    out = out << 8; 
    return out; 
} 

最適化された。私はスピードとサイズの要件を省略し、単にビューのプログラマの観点から最も適切であるものを尋ねることができる分間

q23 a; 
q23 b; 

    mul_inplace_both_pointers(&a, &b); 
    mul_inplace_one_pointer (&a, b); 
a = mul_inplace_no_pointers ( a, b); 

+1

最適である必要がある場合は、3つのプロファイルとプロファイルをすべてコンパイルします。生成されたasmも見てください。しかし、このような単純な関数呼び出しを使用すると、インライン化されていない限り、実行時間が損なわれます。それをチェックする価値があるでしょう。 –

+0

'' type_ef23'はどんな型ですか? –

+1

ae_q23型がint(私が疑うところによると)型のパラメータがおそらく最も速いバージョンのレジスタにも渡されているのであれば、最後のバージョンははるかに優れています(私の意見)。 – Marco

答えて

1

大まかには、関数に渡されるポインタの数をできるだけ少なくすることです。 (1)引数の値を変更する必要がある場合、または(2)値渡しがオーバーヘッドを伴う場合(たとえば、非常に大きなデータ構造)。あなたが機能のごmul_inplace_XXX()スタイルのような機能を使用する必要がある場合

ので、私はおそらくあなたの特定のケースではmul_inplace_one_pointer()機能...

を選ぶだろう - ae_q23が何であるかに応じて、私は使用しません機能は全くありません。私は単純に行うだろう

inout *= in; 
    inout <<= 8; 

表向きの呼び出し元ではなく。または、テストの対象となります。

inout = (inout * in) << 8; 

明らかに私は、操作が未定義または意図しない(意図しない)動作を導入していないと想定しています。

パフォーマンス面では、絶対的な保証はほとんどありません。ターゲットプラットフォームで確実にテストとプロファイルを作成できます。テスト/プロファイリングなしで最適化しようとすることは、いくつかの理由から「時期尚早最適化」と呼ばれます。特に、あなたが手作業で愛用しているコードは、

関連する問題