6

C# でパフォーマンスが重要なアプリケーションを作成していますが、コア操作は重みの計算です。関数は次のようになります。

public void ForEachWeight(Action<int, int, float> action)
{
    for (int lower = 0; lower < LowerLayerSize; lower++) {
        for (int upper = 0; upper < UpperLayerSize; upper++) {
            action(lower, upper, Weights[(lower * UpperLayerSize) + upper]);
        }
    }
}

そして、次のようなさまざまな単純な関数を使用して、何十もの場所で呼び出されます。

if (activationMethod == ActivationMethod.Binary) {
    ForEachWeight((lower, upper, weight) => upperLayer.Values[upper] += weight;
} else {
    ForEachWeight((lower, upper, weight) => upperLayer.Values[upper] += lowerLayer.Values[lower] * weight);
}

すべての呼び出しは同じクラス内から行われるため、すべての変数にアクセスできます。C# はこれらの関数呼び出しをインライン化できますか? たとえば、上記の呼び出しを次のようにインライン化できると考えています。

if (activationMethod == ActivationMethod.Binary) {
    for (int lower = 0; lower < LowerLayerSize; lower++) {
        for (int upper = 0; upper < UpperLayerSize; upper++) {
            upperLayer.Values[upper] += weight;
        }
    }
} else {
    for (int lower = 0; lower < LowerLayerSize; lower++) {
        for (int upper = 0; upper < UpperLayerSize; upper++) {
            upperLayer.Values[upper] += lowerLayer.Values[lower] * weight);
        }
    }
}

そうでない場合は、何万もの余分な関数呼び出しが発生することを意味し、これは大きなオーバーヘッドになると思います。これにより速度が 10% 向上するだけでも、それだけの価値があります。多くのコードを書き直さなければならないため、手動でインライン化して比較することで簡単にベンチマークを行うことはできません。

私の質問は、C# でこれらの呼び出しをインライン化できますか? もしそうなら、どうすればそれらがインライン化されているかを知ることができますか?

4

2 に答える 2

11

インライン化は JIT コンパイル時に発生するため、実行時にコードを検査してインライン化を観察する必要があります。これはデバッガーを使用して行うことができますが、CLR がデバッガーの存在を検出すると、さまざまな最適化が無効になることに注意してください。そのため、メソッドのコンパイル後にデバッガーをアタッチする必要があります。

WinDbg/SOS を使用してメソッドを見つける方法については、これらの 回答を参照してください。

于 2013-03-30T01:34:30.147 に答える
3

この属性内で MethodImplOptions.AggressiveInlining を使用できます: http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimplattribute.aspx

于 2013-03-30T03:57:33.840 に答える