Приветствую, уважаемые!
На днях занимался оптимизацией своего кода и пришел к выводу, что оптимизация VS сломала все мои понятия о "правильном" коде. Чисто случайно наткнулся на забавную вещь:
double res = (int)Math.Round(1.4);
.NET 4.5, в релизе, x86, со включенной оптимизацией работает в 1.5 раза быстрее, чем
double res = Math.Round(1.4);
Я сразу полез в дизассемблированный код, и наткнулся на строки, из-за которых и пишу вам:
double res = (int)Math.Round(1.4);
004E2643 sub esp,0Ch
004E2646 fld qword ptr ds:[4E2678h]
004E264C fistp dword ptr [ebp-0Ch]
004E264F mov eax,dword ptr [ebp-0Ch]
004E2652 mov dword ptr [ebp-0Ch],eax
004E2655 fild dword ptr [ebp-0Ch]
Два дня ломаю мозг, не могу понять, что делают в данном случае команды mov? Может у вас есть идеи?
По просьбам, добавлю:
double res = Math.Round(1.4);
00432646 fld qword ptr ds:[432670h]
0043264C frndint
Ответ
про firstp я нашел вот что
Различные ошибки в этой команде могут встречаться на процессорах
Pentium. В процессоре Pentium III существуют некоторые ситуации, когда
команды FST, FSTP, FIST и FISTP с операндом в памяти не генерируют
исключения #P несмотря на проблемы с точностью. Обратитесь к
технической документации Intel за описанием всех возможных случаев
проявления ошибки. Для однозначного устранения всех предпосылок
возникновения этой ошибки используется две команды NOP перед
критической командой FPU.
У вас после fistp через те самые 2 mov которые ничего вроде не делают идет fild. Можно ли ее принять за критическую команду FPU? Скорее да чем нет, а может закладка на все случаи жизни.
Так что я бы сказал эти 2 mov работают как упомянутые выше 2 NOP. А может даже лучше.
Комментариев нет:
Отправить комментарий