12

Przeportowaliśmy aplikację VS2013 C++/MFC na VS2015 i mamy dość niepokojące problemy z wydajnością i kodem generowanym przez kompilator VS2015.Wydajność log10() w Visual Studio 2015 o wiele wolniej niż w Visual Studio 2013 dla x86

Uwaga jest to dla x86.

Jest to wartość wolniejsza dla wywołań log10(). Podczas profilowania wersji Release przy użyciu samplowania procesora widzimy, że te połączenia zajmują o wiele więcej czasu niż wcześniej. Idąc z np. 49 próbek w tym samym cyklu dla VS2013 do aż 7545 próbek dla tego samego przebiegu w VS2015. Oznacza to, że ta funkcja zmienia się z 0,6% obciążenia procesora na 50% dla danej aplikacji.

W VS2013 Profiler pokazuje:

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

W VS2015 Profiler pokazuje:

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

Dlaczego inna nazwa funkcji?

Przyjrzeliśmy się pokrótce wygenerowanemu zestawowi dla log10. W przypadku VS2013 jest to przekazywane pod numer disp_pentium4.inc i log10_pentium4.asm. W VS2015 jest inaczej. Wygląda na to, że VS2015 powraca do debugowania w wersji __libm_sse2_log10.

Czy przyczyną różnic wydajności może być tylko __sse2_log102? Sprawdziliśmy, czy wyniki wywoływane przez funkcje wywołujące te są w spodziewanych różnicach zmiennoprzecinkowych.

Jesteśmy kompilacji z docelowym v140_xp i mają następujące kompilacji opcje:

/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 

Przedstawiono również tutaj podczas przeglądania właściwości:

Optimization

Code generation

Wszystkie ustawienia projektu są to samo dla VS2013 i VS2015. Zauważ, że używamy SSE2 i mamy ustawiony model zmiennoprzecinkowy na szybki.

Czy ktoś napotkał ten sam problem i wie, jak to naprawić?

+0

Jedną rzeczą, która przychodzi do głowy to, że Microsoft znacznie przepisany swoich bibliotek, cf. [ten post na blogu] (http://blogs.msdn.com/b/vcblog/archive/2015/09/25/rejuvenating-the-microsoft-c-c-compiler.aspx), w tym ich bibliotekę matematyczną. Przepis prawdopodobnie mieści się między dwiema porównywanymi wersjami. –

+1

Wszystko wskazuje na implementację "__sse2_log102" w VS2015, ponieważ jest wolniejsza niż stara implementacja. Jeśli zamieniamy wywołanie na "log10()" z wywołaniem funkcji ippsLog10_64f_A53, ta regresja wydajności zostanie usunięta. – nietras

+0

@PeterSchneider Dzięki, tak, byliśmy tego świadomi, ponieważ port, który mieliśmy, miał problemy z formatowaniem zmiennoprzecinkowym, który również został całkowicie przepisany. – nietras

Odpowiedz

5

Tutaj mój komentarz jako odpowiedź.

Wydaje się, że VS2015 zmienił implementację od log10 uwalniania buduje, gdzie nazywa ten nowy __sse2_log102 funkcję zamiast starego __libm_sse2_log10 i że ta nowa realizacja jest przyczyną ogromnej różnicy wydajności.

Rozwiązaniem dla nas w tym przypadku było wywołanie implementacji dostępnej w bibliotece Intels Performance Primitives (IPP). Na przykład. zamiast dzwonić:

return log10(v); 

nazywają to zamiast:

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

Spowodowało kwestii wydajności zniknie, w rzeczywistości było nieco szybciej przy użyciu starego IPP 7.0 uwolnienia. Jednak nie wszyscy mogą korzystać i płacić za IPP, więc mamy nadzieję, że Microsoft to naprawi.

Poniżej znajduje się wersja VS2015, która pokazała ten problem.

enter image description here

Powiązane problemy