Log10() на Visual Studio 2015 намного медленнее, чем Visual Studio 2013 для x86

Мы портировали VS2013 приложение С++/MFC на VS2015 и имеем некоторые довольно тревожные проблемы с производительностью и кодом, сгенерированным компилятором VS2015.

Обратите внимание, что это для x86.

Это меньше, чем при звонках log10(). При профилировании сборки Release с использованием выборки процессора мы видим, что эти вызовы занимают гораздо больше времени, чем раньше. Переход от, например, 49 образцов в том же прогоне для VS2013 до колоссальных образцов 7545 для одного и того же запуска в VS2015. Это означает, что эта функция идет от 0,6% загрузки процессора до 50% для рассматриваемого приложения.

В VS2013 профилировщик показывает:

Function Name   Inclusive Samples   Exclusive Samples   Inclusive Samples % Exclusive Samples %
__libm_sse2_log10   49  49  0.61    0.61

В VS2015 профайлер показывает:

Function Name   Inclusive Samples   Exclusive Samples   Inclusive Samples % Exclusive Samples %
___sse2_log102  7,545   7,545   50.43   50.43

Почему другое имя функции?

Мы кратко рассмотрели созданную сборку для log10. На VS2013 это перейдет в disp_pentium4.inc и log10_pentium4.asm. На VS2015 это другое. Кажется, VS2015 возвращается в __libm_sse2_log10 в Debug.

Может ли __sse2_log102 быть причиной этой разницы в производительности? Мы проверили, что результаты, полученные от функций, вызывающих их, находятся в пределах ожидаемых разностей с плавающей запятой.

Мы компилируем с целевым v140_xp и имеем следующие параметры компиляции:

/Yu"stdafx.h" /MP /GS- /GL /analyze- /W4 /wd"4510" /wd"4610" /Zc:wchar_t /Z7 /Gm- /Ox /Ob2 /Zc:inline /fp:fast /D "WINVER=0x0501" /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "_CRT_SECURE_NO_WARNINGS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_SCL_SECURE_NO_WARNINGS" /D "_USING_V110_SDK71_" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /GR /arch:SSE2 /Gd /Oy /Oi /MT 

Также отображается при просмотре свойств:

Оптимизация

Генерация кода

Все настройки проекта одинаковы для VS2013 и VS2015. Обратите внимание, что мы используем SSE2 и имеем плавную модель, установленную для быстрого.

Кто-нибудь сталкивался с той же проблемой и знал, как это исправить?

Ответ 1

Вот мой комментарий как ответ.

Похоже, что VS2015 изменил реализацию log10 в сборках релизов, где он называет эту новую функцию __sse2_log102 вместо старой __libm_sse2_log10 и что эта новая реализация является причиной огромной разницы в производительности.

Исправление для нас в этом случае состояло в том, чтобы вызвать реализацию, доступную в библиотеке Intils Performance Primitives (IPP). Например. вместо вызова:

return log10(v);

Назовите это вместо:

double result;
ippsLog10_64f_A53(&v, &result, 1);
return result;

Это привело к тому, что проблема с производительностью исчезла, на самом деле она была немного быстрее, используя старую версию IPP 7.0. Однако не все могут использовать и оплачивать IPP, поэтому мы надеемся, что Microsoft исправит это.

Ниже приведена версия VS2015, которая показала эту проблему.

введите описание изображения здесь