3

組み込みの速度を使用するカイ二乗プログラムをウォークスルーして理解しようとしています。このプロセスで、理解できないコード行に出くわしました。

教科書、Google、このサイトの検索を見直してみましたが、うまくいきませんでした。問題は、構文について何も知らずに、関連する結果を得るのに十分な用語またはキーワードで検索を説明できないことだと思います。

理解できないコード行は次のとおりです。

float (*chi2_float)(const int, const float*, const float*) = chi2_baseline_float;

そして、これを含む関数は次のとおりです。

float chi2_float(const int dim, const float* const x, const float* const y) {
    float (*chi2_float)(const int, const float*, const float*) = chi2_baseline_float;
#ifdef __SSE__
    chi2_float = chi2_intrinsic_float;
#endif
    return chi2_float(dim, x, y);
}

おそらく関数を宣言および定義しているように見えます。行をコメントアウトして再コンパイルすると、次のようになります。

エラー C2659: '=' : 行 chi2_float = chi2_intrinsic_float の左オペランドとして機能します。

必要に応じて、この関数を含む .h ファイルを送信できますが、パラメーターから期待されるとおりです。

どんな助けでも大歓迎です。

4

5 に答える 5

11

問題の行は、 の値に応じて、関数ポインタ型の変数を他の 2 つの関数のいずれかに設定しています__SSE__

次に、chi2_float が指す関数を呼び出し、結果を返します。

于 2012-11-17T22:10:43.337 に答える
7

これ:

float (*chi2_float)(const int, const float*, const float*)= chi2_baseline_float;

関数ポインタ名を宣言し、 という名前chi2_floatの関数へのポインタをそれに割り当てますchi_baseline_float

次に、__SSE__マクロが定義されている場合、ポインターは関数へのポインターで再割り当てされますchi2_intrinsic_float

これらすべての最終的な効果は、次のようなものです。

float chi2_float(const int dim, const float* const x, const float* const y) 
{
#ifdef __SSE__
    return chi2_intrinsic_float(dim, x, y);
#else
    return chi2_baseline_float(dim, x, y);
#endif
}
于 2012-11-17T22:15:04.717 に答える
1
float chi2_float(const int dim, const float* const x, const float* const y) {
   float (*chi2_float)(const int, const float*, const float*) = chi2_baseline_float;
#ifdef __SSE__
   chi2_float = chi2_intrinsic_float;
#endif
   return chi2_float(dim, x, y);
}

ぶさいくな。

このコードを修正するために最初に行うことは、関数ポインター変数の名前として関数名以外のものを使用することです。この変数が関数の名前を覆い隠しているのは、JamesCrowの混乱の原因だと思います。

このコードを修正するために行う2番目のことは、関数ポインターを完全に削除することです。その結果、MichaelBurrが彼の回答にコードを投稿します。

于 2012-11-17T23:54:52.990 に答える
1

いくつかのコメントを含む質問のコード:

// beginning of the definition of function chi2_float 
float chi2_float(const int dim, const float* const x, const float* const y) {
    // declare the variable chi2_float as a function pointer
    // set variable chi2_float to the address of the function chi2_baseline_float
    float (*chi2_float)(const int, const float*, const float*) = chi2_baseline_float;
// if macro __SSE__ is defined (if the compiler enables SSE instructions set)
// [this is your case because you got an error in the below line when you have commented the above line] 
#ifdef __SSE__
    // then preprocessor adds the following line that sets again the variable chi2_float (but to another function) 
    chi2_float = chi2_intrinsic_float;
#endif
    // call the function pointed by the variable chi2_float
    return chi2_float(dim, x, y);
}
于 2012-11-17T22:19:45.497 に答える
1

Michael Burr は次のように提案しました。

float chi2_float(const int dim, const float* const x, const float* const y) 
{
#ifdef __SSE__
    return chi2_intrinsic_float(dim, x, y);
#else
    return chi2_baseline_float(dim, x, y);
#endif
}

コンパイラのオプティマイザをしばらく無視します。これは改善されるかもしれません。Burr 氏のソリューションでは、2 つの関数呼び出しが使用されています。これは、次のように 1 つの関数呼び出しに減らすことができます。

#ifdef __SSE__
    #define chi2_float(dim, x, y) chi2_intrinsic_float(dim, x, y)
#else
    #define chi2_float(dim, x, y) chi2_baseline_float(dim, x, y)
#endif

Burr 氏の chi2_float() を「インライン」として宣言することで、同じ結果が得られる可能性があります。

ただし、現実の世界 (コンパイラがコードを積極的に最適化する場所) に戻ると、優れたオプティマイザーが余分な関数呼び出しを削除し、Burr 氏のソリューションを同じくらい高速にすることが期待できます。

完全を期すために、このディスカッションを投稿しました。これは Burr 氏のソリューションを改善するものではありませんが、もう少しコンテキストが追加されます。技術的には、新しい回答ではなくコメントである必要がありますが、コメントでソース コードをフォーマットすることはできません。それが人生だ。

于 2012-11-18T01:48:15.217 に答える