HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Наш форум > Технические вопросы > Почему MSVC2010 генерирует такой дерьмовый код?
Самая обычная функция max для float-ов
Страницы (3): [1] 2 3 »   Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34524
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Почему MSVC2010 генерирует такой дерьмовый код?

Сегодня с удивлением заметил проблему: колоссальное падение производительности при попытке вычислить максимальное значение. Код вот такой:

C++ Source Code:
float f = somestuff;
f = max( f, 0 );

max стандартно определён как макрос в minmax.h:
C++ Source Code:
#ifndef max
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif

Так вот этот код, будучи скомпилирован в MSVC2010, выполняется в три (!) раза медленнее, чем в MinGW!
Смотрим ассемблер:
code:
fld DWORD PTR _dp$68919[ebp] fcom ST(1) fnstsw ax test ah, 65 ; 00000041H jne SHORT $LN26@Mathlib_In@6 fstp DWORD PTR tv194[ebp] jmp SHORT $LN21@Mathlib_In@6 $LN26@Mathlib_In@6: fstp ST(0) fst DWORD PTR tv194[ebp] $LN21@Mathlib_In@6: fld DWORD PTR tv194[ebp]

Вот что это за дерьмецо, товарищи? Какого чёрта он лезет за нулём в стек? Проверяет контрольное слово, вынося его в ax? Джампы какие-то? И ладно бы, в дебаге. Это В РЕЛИЗЕ, при максимальной оптимизации!
А вот что генерит MinGW:
code:
fldz fxch %st(1) fcomi %st(1), %st fcmovb %st(1), %st fstp %st(1)

Красивый и быстрый код. Ноль берём из fldz, выбор значения делаем специально сделанной для этого кондишнл-инструкцией fcmovb.
Ну, собсно, два вопроса:
1) Почему компилятор MSVC2010 - говно наипреговённейшее, говнявое, преговённое, которое без предупреждения генерит в релизе такой жутко неоптимальный код?
2) Как обойти эту проблему? Я и темплейт-функциями пытался, и опции компилятора всякие крутил. Нифига. Вот стабильно такой код. Ощущение, будто в Microsoft не знают половину инструкций сопроцессора. Но это же бред, верно? Но зато теперь понятно, почему волатила так тормозит.

А может быть, это только мой компилятор взбесился? У других всё нормально?

__________________

Сообщить модератору | | IP: Записан
Сообщение: 146556

Старое сообщение 08-05-2015 01:21
-
 Skaarj
Ctrl+S

Дата регистрации: Aug 2006
Проживает: Twisting Nether
Сообщений: 2382
Нанёс повреждений: 9 ед.

Рейтинг



Награды
  
[2 награды]


А если заменить ассемблерной вставкой и забыть про это?

Сообщить модератору | | IP: Записан
Сообщение: 146561

Старое сообщение 08-05-2015 05:55
-
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



Skaarj раз этот код такой, то и весь остальной такой же. Не на ассемблере же теперь писать. Проще компилировать через minGW, но это может не вариант.
Попробую посмотреть позже как на vs2013.
Можно полный пример кода? Чтобы функцию оптимизацией не откинуло.

Сообщить модератору | | IP: Записан
Сообщение: 146564

Старое сообщение 08-05-2015 06:39
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34524
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
ComradeAndrew писал:
Можно полный пример кода? Чтобы функцию оптимизацией не откинуло.

C++ Source Code:
1
void Mathlib_Internal_TransformVectorsLV_SingleBone( int count, const float *inputVectors, const vmd_matrix_t *inputMatrices, const float *lightDir, float *outputVectors )
2
{
3
  for ( ; count > 0; --count, inputVectors += 4, outputVectors += 4 ) {
4
    outputVectors[0] = inputVectors[0] * inputMatrices[0][0][0] + inputVectors[1] * inputMatrices[0][0][1] + inputVectors[2] * inputMatrices[0][0][2] + inputMatrices[0][0][3];
5
    outputVectors[1] = inputVectors[0] * inputMatrices[0][1][0] + inputVectors[1] * inputMatrices[0][1][1] + inputVectors[2] * inputMatrices[0][1][2] + inputMatrices[0][1][3];
6
    outputVectors[2] = inputVectors[0] * inputMatrices[0][2][0] + inputVectors[1] * inputMatrices[0][2][1] + inputVectors[2] * inputMatrices[0][2][2] + inputMatrices[0][2][3];
7
    float dp = outputVectors[0] * lightDir[0] + outputVectors[1] * lightDir[1] + outputVectors[2] * lightDir[2] - 0.5f;
8
    outputVectors[3] = max( dp, 0.0f );
9
  }
10
}


Цитата:
Skaarj писал:
А если заменить ассемблерной вставкой и забыть про это?

Не получится. Этот код полагается на содержимое стека сопроцессора. Если выносить в отдельную функцию - потребуются дополнительные fld/fsp, и теряются возможности по оптимизации типа instruction flow.
Это во-первых. А во-вторых, в 64-битном коде всё компилируется с использованием SSE-инструкций (неоптимально, конечно, но тем не менее), и FPU-код там будет не в тему.

__________________

Сообщить модератору | | IP: Записан
Сообщение: 146567

Старое сообщение 08-05-2015 08:36
-
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



XaeroX
Вроде получил код с простым примером.
Platform Toolset v120
оптимизация /O2

code:
012D101F movss xmm0,dword ptr [f] 012D1024 xorps xmm1,xmm1 012D1027 add esp,8 012D102A comiss xmm0,xmm1 012D102D ja main+37h (012D1037h) 012D102F movaps xmm0,xmm1 012D1032 movss dword ptr [f],xmm0

Сообщить модератору | | IP: Записан
Сообщение: 146568

Старое сообщение 08-05-2015 09:52
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34524
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
ComradeAndrew писал:
Platform Toolset v120

Ставь тулсет v100. И отключи /arch:SSE, если стоит.

__________________

Сообщить модератору | | IP: Записан
Сообщение: 146569

Старое сообщение 08-05-2015 10:09
-
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



XaeroX
Достать у MS старые версии VS не так-то просто.

>>И отключи /arch:SSE
Где отключить?

Платформа x64?
Platform Toolset v100; /O2

code:
00007FF6830D1025 movss xmm0,dword ptr [f] 00007FF6830D102B xorps xmm1,xmm1 00007FF6830D102E comiss xmm0,xmm1 00007FF6830D1031 ja main+3Ch (07FF6830D103Ch) 00007FF6830D1033 movaps xmm0,xmm1 00007FF6830D1036 movss dword ptr [f],xmm0


Добавлено 08-05-2015 в 13:59:

А нет. То что сверху, это v120 на x64. Я не уследил, когда платформу выставил.
Для v100 x86 /O2
code:
00371013 fldz 00371015 fcom dword ptr [f] 00371018 add esp,8 0037101B fnstsw ax 0037101D test ah,5 00371020 jnp main+27h (0371027h) 00371022 fstp dword ptr [f] 00371025 jmp main+29h (0371029h) 00371027 fstp st(0)

Сообщить модератору | | IP: Записан
Сообщение: 146571

Старое сообщение 08-05-2015 10:59
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34524
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Ну получше, по крайней мере есть fldz.
Но всё равно не так красиво, как в MinGW/GCC.
Это ты 2013-й студией компилил с тулсетом v100?

__________________

Сообщить модератору | | IP: Записан
Сообщение: 146585

Старое сообщение 08-05-2015 18:06
-
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



XaeroX
Да. 2013 студия с тулсетом от visual studio 2010 express.
Как я понял с этой express нельзя на x64 компилировать. По крайней мере, мне написало, что тулсет не установлен.
Хорошо хоть community edition теперь сделали, где, вроде, ничего не урезано и можно vs assist поставить.

Сообщить модератору | | IP: Записан
Сообщение: 146586

Старое сообщение 08-05-2015 19:20
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34524
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Меня 2010 студия во всём устраивала. До вчерашнего дня, пока не обнаружился этот досадный баг. Который, по всей видимости, частично и в 2013 остался - раз код по-прежнему недостаточно оптимален.
Переходить на MinGW не вариант, там своих проблем хватает. В целом микрософтовский компилятор мне показался надёжнее. Но вот как это говно забороть-то?

__________________

Сообщить модератору | | IP: Записан
Сообщение: 146587

Старое сообщение 08-05-2015 19:23
-
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



XaeroX
Могу попробовать ещё на vs 2015. Для сравнения, так сказать. Исправились ли они или ошибки тащат в следующие релизы.
И в саппорт, наверное, им надо репортнуть. Может что скажут.

Сообщить модератору | | IP: Записан
Сообщение: 146588

Старое сообщение 08-05-2015 19:32
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34524
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
ComradeAndrew писал:
Могу попробовать ещё на vs 2015.

Попробуй, пожалуйста.
Но, возможно, они уже забили на тулсет 100.
Цитата:
ComradeAndrew писал:
Может что скажут.

А то я не знаю, что они скажут. Скажут "купите виндовс 10 и вижуал студию 2015, а тулсет 100 - легаси и депрекейтед".
А то, что вы хотите поддерживать процессоры без SSE - это ваши глубоко личные проблемы.

__________________

Сообщить модератору | | IP: Записан
Сообщение: 146590

Старое сообщение 08-05-2015 19:48
-
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



XaeroX
v140 x86 /O2

code:
012810C3 movss xmm0,dword ptr [esp+40h] 012810C9 xorps xmm1,xmm1 012810CC add esp,8 012810CF comiss xmm0,xmm1 012810D2 ja main+3Dh (012810DDh) 012810D4 movaps xmm0,xmm1 012810D7 movss dword ptr [esp+38h],xmm0

Сообщить модератору | | IP: Записан
Сообщение: 146591

Старое сообщение 08-05-2015 21:19
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34524
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


ComradeAndrew
Опять ты SSE-код показываешь. Да знаю я, знаю, что под SSE нормально всё. В 2010 тоже нормально под х64. Меня интересует исключительно FPU-код, совместимый.

__________________

Сообщить модератору | | IP: Записан
Сообщение: 146594

Старое сообщение 09-05-2015 03:04
-
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



XaeroX а где отключать-то?

Сообщить модератору | | IP: Записан
Сообщение: 146595

Старое сообщение 09-05-2015 05:01
- За что?
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 07:10. Новая тема    Ответить
Страницы (3): [1] 2 3 »   Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Наш форум > Технические вопросы > Почему MSVC2010 генерирует такой дерьмовый код?
Самая обычная функция max для float-ов
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

Быстрый переход:
Оцените эту тему:

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

На основе vBulletin
Авторское право © 2000 - 2002, Jelsoft Enterprises Limited.
Дизайн и программирование: Crystice Softworks © 2005 - 2024