2013-03-06 9 views
5

मैं कोड है जो जो अप (प्रोफाइलर के अनुसार) मेरी CPU समय के 10% के आसपास कुल में, लगता है,_ftol2_sse, क्या तेज़ विकल्प हैं?

int myNumber = (int)(floatNumber); 

का एक बहुत कॉल की है। मैं यह है कि कम से छोड़ सकता है, मुझे आश्चर्य है कि अगर वहाँ तेजी से विकल्प हैं, इसलिए मैं चारों ओर खोज की कोशिश की, और

http://devmaster.net/forums/topic/7804-fast-int-float-conversion-routines/ http://stereopsis.com/FPU.html

मैं Real2Int() दी समारोह को लागू करने की कोशिश की पर ठोकर खाई , लेकिन यह मुझे गलत परिणाम देता है, और धीमा चलता है। अब मुझे आश्चर्य है, क्या फर्श डबल/फ्लोट वैल्यू को पूर्णांक में तेज कार्यान्वयन हैं, या एसएसई 2 संस्करण जितना तेज़ हो जाता है? जिन पृष्ठों को मैंने पाया वह थोड़ा सा समय है, इसलिए यह पुराना हो सकता है, और इस पर नया एसटीएल तेज है।

वर्तमान कार्यान्वयन करता है:

013B1030 call  _ftol2_sse (13B19A0h) 

013B19A0 cmp   dword ptr [___sse2_available (13B3378h)],0 
013B19A7 je   _ftol2 (13B19D6h) 
013B19A9 push  ebp 
013B19AA mov   ebp,esp 
013B19AC sub   esp,8 
013B19AF and   esp,0FFFFFFF8h 
013B19B2 fstp  qword ptr [esp] 
013B19B5 cvttsd2si eax,mmword ptr [esp] 
013B19BA leave 
013B19BB ret 

संबंधित सवाल मैंने पाया:

Fast float to int conversion and floating point precision on ARM (iPhone 3GS/4)

What is the fastest way to convert float to int on x86

दोनों के बाद से पुराने हैं, या एआरएम आधारित, मैं कर रहे हैं आश्चर्य है कि वहाँ हैं ऐसा करने के मौजूदा तरीके। ध्यान दें कि यह कहता है कि सबसे अच्छा रूपांतरण ऐसा नहीं होता है, लेकिन मुझे इसे प्राप्त करने की आवश्यकता है, इसलिए यह संभव नहीं होगा।

उत्तर

6

यदि आप जेनेरिक x86 हार्डवेयर को लक्षित कर रहे हैं तो इसे हरा करना मुश्किल होगा। रनटाइम यह सुनिश्चित करने के लिए नहीं जानता कि लक्ष्य मशीन में एसएसई इकाई है। अगर ऐसा होता है, तो यह कर सकता है कि x64 संकलक क्या करता है और cvttss2si ऑपोड इनलाइन करता है। लेकिन चूंकि रनटाइम को यह जांचना है कि कोई एसएसई इकाई उपलब्ध है या नहीं, तो आपको वर्तमान कार्यान्वयन के साथ छोड़ दिया गया है। ftol2_sse का कार्यान्वयन यही है। और यह एक x87 रजिस्टर में मान को और अधिक पास करता है और फिर एसएसई इकाई उपलब्ध होने पर इसे एसएसई रजिस्टर में स्थानांतरित कर देता है।

आप एसएसई इकाइयों वाली मशीनों को लक्षित करने के लिए x86 कंपाइलर को बता सकते हैं। फिर संकलक वास्तव में एक साधारण cvttss2si ऑपोड इनलाइन उत्सर्जित करेगा। यह उतना तेज़ होगा जितना आप प्राप्त कर सकते हैं। लेकिन अगर आप पुरानी मशीन पर कोड चलाते हैं तो यह असफल हो जाएगा। शायद आप दो संस्करणों की आपूर्ति कर सकते हैं, एक एसएसई के साथ मशीनों के लिए, और बिना किसी के लिए।

यह आपको इतना कुछ हासिल नहीं करेगा। यह ftol2_sse के सभी ओवरहेड से बचने जा रहा है जो वास्तव में cvttss2si ऑपोड तक पहुंचने से पहले होता है जो काम करता है।

आईडीई से कंपाइलर सेटिंग्स को बदलने के लिए, प्रोजेक्ट> गुण> कॉन्फ़िगरेशन गुण> सी/सी ++> कोड जनरेशन> उन्नत निर्देश सेट सक्षम करें का उपयोग करें। कमांड लाइन पर यह/arch: एसएसई या/आर्क: एसएसई 2 है।

+0

सही, x64 कोड के साथ यह बहुत तेज़ काम करता है! – SinisterMJ

1

double के लिए मुझे नहीं लगता कि आप बहुत परिणामों में सुधार करने में सक्षम हो जाएगा, लेकिन यदि आप float रों का एक बहुत कन्वर्ट करने के लिए है कि एक पैक रूपांतरण का उपयोग मदद कर सकता है, निम्नलिखित nasm कोड है:

global _start 

section .data 
    align 16 
    fv1: dd 1.1, 2.5, 2.51, 3.6 

section .text 
    _start: 

    cvtps2dq xmm1, [fv1] ; Convert four 32-bit(single precision) floats to 32-bit(double word) integers and place the result in xmm1 

इंट्रिनिक्स कोड होना चाहिए जो आपको एक ही चीज़ को एक आसान तरीके से करने की अनुमति देता है लेकिन मैं इंट्रिनिक्स पुस्तकालयों का उपयोग करने से परिचित नहीं हूं। यद्यपि आप gcc का उपयोग नहीं कर रहे हैं इस आलेख Auto-vectorization with gcc 4.7 एक आंख खोलने वाला है कि संकलक को अच्छे वेक्टरकृत कोड उत्पन्न करने के लिए कितना मुश्किल हो सकता है।

1

यदि आपको गति और लक्ष्य मशीनों का एक बड़ा आधार चाहिए, तो आप अपने सभी एल्गोरिदम के साथ-साथ एक सामान्य एक तेज़ एसएसई संस्करण बेहतर ढंग से पेश करेंगे - और एल्गोरिदम को उच्च स्तर पर निष्पादित करने के लिए चुनें।

इसका यह भी अर्थ होगा कि एसबीई के लिए भी एबीआई अनुकूलित किया गया है; और जब आप उपलब्ध होने पर गणना को सदिश कर सकते हैं और यह भी कि आर्किटेक्चर के लिए नियंत्रण तर्क अनुकूलित किया गया है।

बीटीडब्ल्यू। यहां तक ​​कि FLD; FIST अनुक्रम पेंटियम पर ~ 7 घड़ी चक्र से अधिक नहीं लेना चाहिए।

+3

सही छंटनी पाने के लिए आपको राउंडिंग मोड को बदलने की जरूरत है। जहां तक ​​मुझे पता है, x87 स्थिति शब्द बदलना धीमा है। –

+0

@ infact की टिप्पणी सटीक है –

+0

अच्छा बिंदु। तब यह समझ में आता है कि स्थिति शब्द _often_ को नहीं बदला जाए। –

संबंधित मुद्दे