Фон
Следующий критический цикл частичного программного обеспечения, написанного на С++, в основном сравнивает два объекта одним из своих членов:
for(int j=n;--j>0;)
asd[j%16]=a.e<b.e;
a
и b
имеют класс ASD
:
struct ASD {
float e;
...
};
Я изучал влияние такого сравнения в облегченной функции-члена:
bool test(const ASD& y)const {
return e<y.e;
}
и используя его следующим образом:
for(int j=n;--j>0;)
asd[j%16]=a.test(b);
Компилятор вставляет эту функцию, но проблема в том, что код сборки будет отличаться и вызывать > 10% издержки выполнения. Я должен задать вопрос:
Вопросы
-
Почему компилятор создает другой код сборки?
-
Почему произведенная сборка медленнее?
EDIT: На второй вопрос ответили предложение @KamyarSouri (j% 16). Теперь код сборки выглядит почти идентичным (см. http://pastebin.com/diff.php?i=yqXedtPm). Единственными отличиями являются линии 18, 33, 48:
000646F9 movzx edx,dl
Материал
- Код проверки: http://pastebin.com/03s3Kvry
- Выход сборки на MSVC10 с /Ox/Ob 2/Ot/arch: SSE2:
- Встроенная версия компилятора: http://pastebin.com/yqXedtPm
- Вручную встроенную версию: http://pastebin.com/pYSXL77f
- Разница http://pastebin.com/diff.php?i=yqXedtPm
В этой диаграмме показан FLOP/s (с коэффициентом масштабирования) для 50 тестовых строк моего кода.
gnuplot script для генерации графика: http://pastebin.com/8amNqya7
Параметры компилятора:
/Zi/W3/WX-/MP/Ox/Ob2/Oi/Ot/Oy/GL/D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm -/EHsc/MT/GS-/Gy/arch: SSE2/fp: точный /Zc: wchar_t/Zc: forScope/Gd/анализ -
Параметры компоновщика: /INCREMENTAL: NO "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /ALLOWISOLATION/MANIFESTUAC: "level = 'asInvoker' uiAccess = 'false'" /SUBSYSTEM: CONSOLE/OPT: REF/OPT: ICF/LTCG/TLBID: 1/DYNAMICBASE/NXCOMPAT/MACHINE: X86/ERRORREPORT: QUEUE