2012-03-13 2 views
2

У меня есть служба WCF, которая использует LINQ to SQL для своего уровня данных. Используются только хранимые процедуры, нет доступа к динамической таблице. Когда я нацеливаюсь на x64, я получаю половину производительности сборки x86. Я проследил путь до Reflection.Emit.DynamicMethod.CreateDelegate. Я создал простой тестовый проект, чтобы продемонстрировать разницу в производительности между двумя платформами.Почему DynamicMethod намного медленнее на x64?

Каково конкретное объяснение того, что DynamicMethod является настолько медленнее на x64? Мое смутное понимание заключается в том, что в x64 может быть добавлен дополнительный кусок, участвующий в DynamicInvoke.


Вот результаты, когда выполняется на Windows, 7 Enterprise x64, Core i7 Q720 @ 1,60 ГГц, однопоточный:

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); 
    } 
} 
+0

Как правило, ваш CreateDelegate не будет во внутреннем цикле, правда? – antlersoft

+0

Это эффективно во внутреннем цикле, когда я выполняю нагрузочное тестирование службы WCF. –

+0

@AidanRyan, Можете ли вы попытаться назвать свой метод Main более одного раза? (переименуйте Main на Main2 и напишите новое Main Main Main2 в цикле). –

ответ

1

I предположил бы, что это связано со скоростью компиляции. Есть много потоков, которые, похоже, указывают, что компиляция JIT для x64 значительно медленнее, чем x86.

В этом случае кто-то видел значительное увеличение производительности в их x64 JIT только потому, что другие зависимые сборки не были NGEN'd. Хотя я сомневаюсь, что это поможет в этом сценарии, вы никогда не знаете, что еще пытается загрузить, что может замедлить его. Возможно, попробуйте запустить команду в ответе и посмотрите, изменит ли это вашу производительность. WPF slow to start on x64 in .NET Framework 4.0

Смежные вопросы