Почему закомментирование первых двух строк этого цикла 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]