Почему добавление локальных переменных делает код.NET медленнее

Почему закомментирование первых двух строк этого цикла for и раскомментирование третьей приводит к ускорению на 42%?

int count = 0;
for (uint i = 0; i < 1000000000; ++i) {
    var isMultipleOf16 = i % 16 == 0;
    count += isMultipleOf16 ? 1 : 0;
    //count += i % 16 == 0 ? 1 : 0;
}

Тайминг сильно отличается от ассемблерного кода. :13 инструкций вместо 7 в цикле. Платформа — Windows 7 под управлением.NET 4.0 x64. Оптимизация кода включена, и тестовое приложение запускалось вне VS2010. [ Обновление:Репропроект , полезно для проверки настроек проекта.]

Устранение промежуточного логического значения — фундаментальная оптимизация, одна из самых простых в моей эре 1980-х Dragon Book . Почему оптимизация не применялась при создании CIL или JIT-компиляции машинного кода x64?

Есть ли переключатель «Действительно компилятор, пожалуйста, оптимизируйте этот код»?Хотя я разделяю мнение, что преждевременная оптимизация сродни любви к деньгам , я мог видеть разочарование в попытке профилировать сложный алгоритм, в подпрограммах которого были разбросаны подобные проблемы. Вы будете работать с горячими точками, но не будете иметь ни малейшего намека на более широкую теплую область, которую можно значительно улучшить, настроив вручную то, что мы обычно принимаем как должное от компилятора. Я очень надеюсь, что я что-то упускаю здесь.

Обновление:Различия в скорости также возникают для x86, но зависят от порядка, в котором методы просто -в -времени компилируются. См. Почему JIT-заказ влияет на производительность?

Код сборки(по запросу):

    var isMultipleOf16 = i % 16 == 0;
00000037  mov         eax,edx 
00000039  and         eax,0Fh 
0000003c  xor         ecx,ecx 
0000003e  test        eax,eax 
00000040  sete        cl 
    count += isMultipleOf16 ? 1 : 0;
00000043  movzx       eax,cl 
00000046  test        eax,eax 
00000048  jne         0000000000000050 
0000004a  xor         eax,eax 
0000004c  jmp         0000000000000055 
0000004e  xchg        ax,ax 
00000050  mov         eax,1 
00000055  lea         r8d,[rbx+rax] 
    count += i % 16 == 0 ? 1 : 0;
00000037  mov         eax,ecx 
00000039  and         eax,0Fh 
0000003c  je          0000000000000042 
0000003e  xor         eax,eax 
00000040  jmp         0000000000000047 
00000042  mov         eax,1 
00000047  lea         edx,[rbx+rax] 

43
задан Community 23 May 2017 в 11:45
поделиться