내 이전 question에 따르면 제 생각은 계수 m_a, m_b가 1.0 또는 0.0 일 때 계산을 제거하여 알고리즘을 최적화하는 것이 었습니다. 이제 알고리즘을 최적화하려고 시도하고 설명 할 수없는 흥미로운 결과를 얻었습니다.SSE FP 장치가 0.0 피연산자를 감지합니까?
첫 번째 분석기는 100,000 개의 샘플에 대해 실행됩니다. 파라미터 값은 파일로부터 판독된다 (!)
B0 = 1.0 B1 = -1.480838022915731 B2 = 1.0
A0 = 1.0 A1 = -1.784147570544337 A2 = 0.854309980957510
둘째 분석기 런 동일한 100k 샘플. 파라미터 값은 파일로부터 판독된다 (!)
B0 = 1.0 = -1.480838022915731 B1 B2 = 1.0
A0 = 1.0 A2 A1 = -1.784147570544337 = 0.0 --- <는 전용 A2가 다르다!
는 수치 내에서 왼쪽에있는 번호 (회색 배경) 필요한 CPU 사이클을 나타냅니다. 매개 변수 a2 = 0.0으로 명확하게 보이는 두 번째 실행은 훨씬 빠릅니다.
디버그 코드와 릴리스 코드의 차이점을 확인했습니다. 릴리스 코드가 더 빠릅니다 (예상대로). 디버그 및 릴리스 코드는 매개 변수 a2가 수정 될 때 동일한 이상한 동작을합니다.
그런 다음 ASM 코드를 확인했습니다. SSE 지침이 사용 된 것으로 나타났습니다. 이것은/arch : SSE2로 컴파일 되었기 때문에 유효합니다. 따라서 나는 SSE를 사용하지 않았다. 결과 코드는 SSE를 더 이상 사용하지 않으며 성능은 매개 변수 값 a2에 더 이상 의존하지 않습니다 (예상대로)
따라서 SSE가 사용될 때 성능 이점이 있다는 결론을 얻었습니다 a2가 0.0임을 감지하고 쓸모없는 곱셈과 뺄셈을 생략합니다. 나는 이것에 대해 결코 들어 보지 못했고 정보를 찾지 만 성공하지는 못했습니다.
내 성능 결과에 대한 설명이 누구에게 있습니까?
00F43EC0 mov edx,dword ptr [ebx]
00F43EC2 movss xmm0,dword ptr [eax+edi*4]
00F43EC7 cmp edx,dword ptr [ebx+4]
00F43ECA je $LN419+193h (0F43F9Dh)
00F43ED0 mov esi,dword ptr [ebx+4]
00F43ED3 lea eax,[edx+68h]
00F43ED6 lea ecx,[eax-68h]
00F43ED9 cvtps2pd xmm0,xmm0
00F43EDC cmp ecx,esi
00F43EDE je $LN419+180h (0F43F8Ah)
00F43EE4 movss xmm1,dword ptr [eax+4]
00F43EE9 mov ecx,dword ptr [eax]
00F43EEB mov edx,dword ptr [eax-24h]
00F43EEE movss xmm3,dword ptr [edx+4]
00F43EF3 cvtps2pd xmm1,xmm1
00F43EF6 mulsd xmm1,xmm0
00F43EFA movss xmm0,dword ptr [ecx]
00F43EFE cvtps2pd xmm4,xmm0
00F43F01 cvtps2pd xmm3,xmm3
00F43F04 mulsd xmm3,xmm4
00F43F08 xorps xmm2,xmm2
00F43F0B cvtpd2ps xmm2,xmm1
00F43F0F movss xmm1,dword ptr [ecx+4]
00F43F14 cvtps2pd xmm4,xmm1
00F43F17 cvtps2pd xmm2,xmm2
00F43F1A subsd xmm2,xmm3
00F43F1E movss xmm3,dword ptr [edx+8]
00F43F23 mov edx,dword ptr [eax-48h]
00F43F26 cvtps2pd xmm3,xmm3
00F43F29 mulsd xmm3,xmm4
00F43F2D subsd xmm2,xmm3
00F43F31 movss xmm3,dword ptr [edx+4]
00F43F36 cvtps2pd xmm4,xmm0
00F43F39 cvtps2pd xmm3,xmm3
00F43F3C mulsd xmm3,xmm4
00F43F40 movss xmm4,dword ptr [edx]
00F43F44 cvtps2pd xmm4,xmm4
00F43F47 cvtpd2ps xmm2,xmm2
00F43F4B xorps xmm5,xmm5
00F43F4E cvtss2sd xmm5,xmm2
00F43F52 mulsd xmm4,xmm5
00F43F56 addsd xmm3,xmm4
00F43F5A movss xmm4,dword ptr [edx+8]
00F43F5F cvtps2pd xmm1,xmm1
00F43F62 movss dword ptr [ecx+4],xmm0
00F43F67 mov edx,dword ptr [eax]
00F43F69 cvtps2pd xmm4,xmm4
00F43F6C mulsd xmm4,xmm1
00F43F70 addsd xmm3,xmm4
00F43F74 xorps xmm1,xmm1
00F43F77 cvtpd2ps xmm1,xmm3
00F43F7B movss dword ptr [edx],xmm2
00F43F7F movaps xmm0,xmm1
00F43F82 add eax,70h
00F43F85 jmp $LN419+0CCh (0F43ED6h)
00F43F8A movss xmm1,dword ptr [ebx+10h]
00F43F8F cvtps2pd xmm1,xmm1
00F43F92 mulsd xmm1,xmm0
00F43F96 xorps xmm0,xmm0
00F43F99 cvtpd2ps xmm0,xmm1
00F43F9D mov eax,dword ptr [ebp-4Ch]
00F43FA0 movss dword ptr [eax+edi*4],xmm0
00F43FA5 mov ecx,dword ptr [ebp-38h]
00F43FA8 mov eax,dword ptr [ebp-3Ch]
00F43FAB sub ecx,eax
00F43FAD inc edi
00F43FAE sar ecx,2
00F43FB1 cmp edi,ecx
00F43FB3 jb $LN419+0B6h (0F43EC0h)
편집 : 대체 디버그 ASM 코드 릴리스 코드에 의해
완성도를 들어이 릴리스 버전에 대한 관련 ASM 코드입니다.
"해당 디버그 버전의 ASM 코드"관련성이있는 이유는 무엇입니까? 최적화되지 않은 코드의 성능 측정은 무의미합니다. –
이미 설명한 바와 같이 : 릴리스 버전은 빠르지 만 디버그 및 릴리스 버전의 동작은 동일합니다. 읽을 수 있기 때문에 디버그 ASM 코드를 첨부했습니다. 릴리스 ASM 코드를 선호하는 경우 첨부 할 수도 있습니다. – Mark
어셈블리 목록을 게시하거나 컴파일 가능한 코드를 게시하는 대신 컴파일러를 완벽하게 실행할 수 있습니다. –