मेरे पास निम्न कोड है और उपयोग किए जाने वाले exp()
फ़ंक्शन के आंतरिक संस्करण की अपेक्षा कर रहा हूं। दुर्भाग्य से, यह एक 64 निर्माण में नहीं है, यह एक ऐसी ही Win32 (यानी, 32-बिट का निर्माण) की तुलना में धीमी कर रही:मैं x64 कोड में exp() फ़ंक्शन के लिए आंतरिक कैसे प्राप्त कर सकता हूं?
#include "stdafx.h"
#include <cmath>
#include <intrin.h>
#include <iostream>
int main()
{
const int NUM_ITERATIONS=10000000;
double expNum=0.00001;
double result=0.0;
for (double i=0;i<NUM_ITERATIONS;++i)
{
result+=exp(expNum); // <-- The code of interest is here
expNum+=0.00001;
}
// To prevent the above from getting optimized out...
std::cout << result << '\n';
}
मैं अपने निर्माण के लिए निम्नलिखित स्विच का उपयोग कर रहा:
/Zi /nologo /W3 /WX-
/Ox /Ob2 /Oi /Ot /Oy /GL /D "WIN32" /D "NDEBUG"
/D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm-
/EHsc /GS /Gy /arch:SSE2 /fp:fast /Zc:wchar_t /Zc:forScope
/Yu"StdAfx.h" /Fp"x64\Release\exp.pch" /FAcs /Fa"x64\Release\"
/Fo"x64\Release\" /Fd"x64\Release\vc100.pdb" /Gd /errorReport:queue
जैसा कि आप देख सकते हैं, मेरे पास /Oi
, /O2
और /fp:fast
MSDN article on intrinsics प्रति आवश्यक है। फिर भी, मेरे प्रयासों के बावजूद मानक पुस्तकालय को कॉल किया गया है, जिससे exp()
x64 बिल्डों पर धीमी गति से प्रदर्शन कर रहा है।
for (double i=0;i<NUM_ITERATIONS;++i)
000000013F911030 movsd xmm10,mmword ptr [[email protected] (13F912248h)]
000000013F911039 movapd xmm8,xmm6
000000013F91103E movapd xmm7,xmm9
000000013F911043 movaps xmmword ptr [rsp+20h],xmm11
000000013F911049 movsd xmm11,mmword ptr [[email protected] (13F912240h)]
{
result+=exp(expNum);
000000013F911052 movapd xmm0,xmm7
000000013F911056 call exp (13F911A98h) // ***** exp lib call is here *****
000000013F91105B addsd xmm8,xmm10
expNum+=0.00001;
000000013F911060 addsd xmm7,xmm9
000000013F911065 comisd xmm8,xmm11
000000013F91106A addsd xmm6,xmm0
000000013F91106E jb main+52h (13F911052h)
}
आप ऊपर विधानसभा में देख सकते हैं, वहाँ exp()
समारोह के लिए बाहर एक फोन है:
यहाँ उत्पन्न विधानसभा है। अब, चलो एक 32-बिट का निर्माण के साथ कि for
पाश के लिए तैयार किए गए कोड को देखो: वहाँ
for (double i=0;i<NUM_ITERATIONS;++i)
00101031 xorps xmm1,xmm1
00101034 rdtsc
00101036 push ebx
00101037 push esi
00101038 movsd mmword ptr [esp+1Ch],xmm0
0010103E movsd xmm0,mmword ptr [[email protected] (102188h)]
00101046 push edi
00101047 mov ebx,eax
00101049 mov dword ptr [esp+3Ch],edx
0010104D movsd mmword ptr [esp+28h],xmm0
00101053 movsd mmword ptr [esp+30h],xmm1
00101059 lea esp,[esp]
{
result+=exp(expNum);
00101060 call __libm_sse2_exp (101EC0h) // <--- Quite different from 64-bit
00101065 addsd xmm0,mmword ptr [esp+20h]
0010106B movsd xmm1,mmword ptr [esp+30h]
00101071 addsd xmm1,mmword ptr [[email protected] (102180h)]
00101079 movsd xmm2,mmword ptr [[email protected] (102178h)]
00101081 comisd xmm2,xmm1
00101085 movsd mmword ptr [esp+20h],xmm0
expNum+=0.00001;
0010108B movsd xmm0,mmword ptr [esp+28h]
00101091 addsd xmm0,mmword ptr [[email protected] (102188h)]
00101099 movsd mmword ptr [esp+28h],xmm0
0010109F movsd mmword ptr [esp+30h],xmm1
001010A5 ja wmain+40h (101060h)
}
बहुत अधिक कोड है, फिर भी यह तेजी से है।
32-बिट:
For loop body average exec time: 34.849229 cycles/10.560373 ns
64-बिट: एक समय परीक्षण मैं एक 3.3 गीगा Nehalem-ईपी मेजबान पर किया निम्नलिखित परिणाम का उत्पादन किया
For loop body average exec time: 45.845323 cycles/13.892522 ns
बहुत अजीब व्यवहार, वास्तव में। ऐसा क्यों हो रहा है?
अद्यतन:
मैं एक Microsoft Connect bug report बनाया है। फ्लोटिंग पॉइंट इंट्रिनिक्स के उपयोग पर विशेष रूप से x64 कोड में माइक्रोसॉफ्ट से आधिकारिक उत्तर प्राप्त करने के लिए इसे अपनाने के लिए स्वतंत्र महसूस करें।
[यह आलेख] (http://blogs.msdn.com/b/ricom/archive/2009/06/10/visual-studio-why-is-there-no-64-bit-version.aspx) (यह बताते हुए कि वीएस में 64 बिट संस्करण क्यों नहीं है) बताता है कि 64 बिट बिल्ड 32 बिट की तुलना में धीमा हो सकता है। मुझे नहीं पता कि यह स्पष्टीकरण वह है जो आपके विशिष्ट मामले पर लागू होता है। – Attila
यह आलेख विजुअल स्टूडियो के 64-बिट संस्करण के बारे में है, इसका सवाल उठाने के लिए कुछ भी नहीं है। ऐसे कई कारक हैं जो 64-बिट अनुप्रयोग को 32-बिट एक से धीमा कर सकते हैं। जब तक, मुझे कुछ याद नहीं आ रहा है, हालांकि इन कारकों में से कोई भी फ्लोटिंग पॉइंट गणना के बारे में मेरे प्रश्न के साथ कुछ भी नहीं करना है। –
@ माइकलगोल्डशेटिन - मेरी गलती – Attila