Почему комментирование первых двух строк этого цикла 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. [Обновление: Repro project, полезно для проверки настроек проекта.]
Устранение промежуточного логического значения - это фундаментальная оптимизация, одна из самых простых в моей 1980-х гг. Dragon Забронируйте. Как оптимизация не применялась при генерации 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]
var
- это компилятор, пожалуйста, выведите тип этой переменной и представьте, что это написал я. В этом случае для себя будет выведеноbool
. - person Damien_The_Unbeliever   schedule 29.04.2012sete
,movzx
иtest
для двух- форма заявления? - person Edward Brey   schedule 30.04.2012