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% 的速度,那是完全值得的。我无法通过手动内联它们进行比较来轻松进行基准测试,因为我必须重写很多代码。

所以我的问题是 CAN 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 回答