为什么DynamicMethod在x64上速度慢得多

本文关键字:速度慢 x64 DynamicMethod 为什么 | 更新日期: 2023-09-27 18:27:46

我有一个WCF服务,它的数据层使用LINQ to SQL。只有存储过程在使用,没有动态表访问。当我以x64为目标时,我获得的吞吐量是x86构建的一半。我已经追踪到Reflection.Emit.DynamicMethod.CreateDelegate的热路径。我创建了一个简单的测试项目来演示两个平台之间的性能差异。

DynamicMethod在x64上速度如此之慢的具体原因是什么?我模糊的理解是,x64上的DynamicInvoke可能涉及到一个额外的thunk。


以下是在Windows 7 Enterprise x64上执行时的结果,Core i7 Q720@1.60 GHz,单线程:

Build Target      Average milliseconds to execute 100,000 iterations
x86               5504
x64               14699
Any CPU           14789

测试代码:

class Program
{
    private delegate string XInvoker(string arg);
    private const int OUTER_ITERATIONS = 4;
    private const int INNER_ITERATIONS = 100000;
    static void Main(string[] args)
    {
        Console.WriteLine("Timing {0} iterations, repeat {1} times...", INNER_ITERATIONS, OUTER_ITERATIONS);
        var watch = new Stopwatch();
        long totalMs = 0;
        for (int outer = 0; outer < OUTER_ITERATIONS; outer++)
        {
            watch.Restart();
            for (int inner = 0; inner < INNER_ITERATIONS; inner++)
            {
                var method = new DynamicMethod("X", typeof(string), new[] { typeof(string) });
                var ilGen = method.GetILGenerator();
                ilGen.Emit(OpCodes.Ldarg_0);
                ilGen.Emit(OpCodes.Ret);
                var del = method.CreateDelegate(typeof(XInvoker));
                var blah = del.DynamicInvoke("blah");
            }
            watch.Stop();
            totalMs += watch.ElapsedMilliseconds;
            Console.WriteLine("Took {0} ms to iterate {1} times", watch.ElapsedMilliseconds, INNER_ITERATIONS);
        }
        Console.WriteLine();
        Console.WriteLine("Overall average: {0} ms to iterate {1} times", totalMs / OUTER_ITERATIONS, INNER_ITERATIONS);
    }
}

为什么DynamicMethod在x64上速度慢得多

我想这与编译速度有关。有很多线程似乎表明x64的JIT编译比x86慢得多。

在这种情况下,有人看到他们的x64 JIT性能显著提高,只是因为其他依赖程序集没有NGEN'd。尽管我怀疑它在这种情况下会有帮助,但你永远不知道它试图加载的其他东西可能会减缓它的速度。也许试着运行答案中的命令,看看这是否会改变你的性能。WPF在.NET Framework 4.0中的x64上启动缓慢