2011-11-28 7 views
10

मैंने एसएसई प्रदर्शन को मापने के लिए ऑनलाइन अपनाया।क्या यह घड़ी इंटेल i3 पर उपयुक्त है?

#ifndef __TIMER_H__ 
#define __TIMER_H__ 

#pragma warning (push) 
#pragma warning (disable : 4035) // disable no return value warning 

__forceinline unsigned int GetPentiumTimer() 
{ 
    __asm 
    { 
     xor eax,eax    // VC won't realize that eax is modified w/out this 
            // instruction to modify the val. 
            // Problem shows up in release mode builds 
     _emit 0x0F    // Pentium high-freq counter to edx;eax 
     _emit 0x31    // only care about low 32 bits in eax 

     xor edx,edx    // so VC gets that edx is modified 
    } 
} 

#pragma warning (pop) 

#endif 

मैं अपने पेंटियम डी E2200 CPU पर माप किया था, और यह ठीक काम करता है (यह पता चलता है गठबंधन SSE निर्देश तेजी से कर रहे हैं)। लेकिन मेरे आई 3 सीपीयू पर मुझे 70% परीक्षणों के अनधिकृत निर्देश मिलते हैं।

क्या आपको लगता है कि यह घड़ी टिक माप i3 CPU के लिए उपयुक्त नहीं है?

+0

मुझे पूरा यकीन है कि वीसी इनलाइन एएसएम में 'आरडीटीएससी' निर्देश का समर्थन करता है। इसके अलावा आप ऊपरी 32-बिट्स की परवाह क्यों नहीं करते हैं, और आपको '__declspec (नग्न) 'का उपयोग करना चाहिए या बेहतर मूल्य में एक मूल्य को बेहतर तरीके से वापस करना चाहिए। इसके अलावा मैं ['QueryPerformanceCounter'] (http: //msdn.microsoft.com/en-us/library/windows/desktop/ms644904 \ (v = vs.85 \) का उपयोग करना चाहता हूं।एएसपीएक्स) या इसके बजाय समान कार्य (आवृत्ति स्केलिंग/बहु-कोर प्रोसेसर आदि के साथ समस्याओं को ध्यान में रखते हुए)। – user786653

+0

आरडीटीएससी * एक धारावाहिक निर्देश नहीं है, जिसका अर्थ यह है कि इसे आदेश से निष्पादित किया जा सकता है। यदि आप इसे सीधे उपयोग करने का आग्रह करते हैं, तो आप आमतौर पर सीरियलाइजेशन को मजबूर करने के लिए CPUID का उपयोग करना चाहते हैं (यह कुछ धारावाहिक निर्देशों में से एक है जिसे आप उपयोगकर्ता मोड में निष्पादित कर सकते हैं)। –

+0

मेरे पास QueryPerformanceCounter भी है। यह परिणामों के अनुसार बहुत विश्वसनीय नहीं है। एनएक्सएन मैट्रिक्स गुणा के लिए, एन = 10000 या उच्चतर, समय केवल 0.3 सेकंड लेता है? मुझे नहीं लगता कि यह बिल्कुल सटीक है (कंसोल पर परिणाम देखने के लिए 2 सेकंड से अधिक समय लगता है), इसलिए मैं घड़ी की टिकों पर जाता हूं। मैं अब RDTSC को आजमाने की कोशिश कर रहा हूं। धन्यवाद। – CppLearner

उत्तर

4

QueryPerformanceCounter (कम से कम विंडोज़ पर) निश्चित रूप से इनलाइन असेंबली से काफी बेहतर है। मुझे उस फ़ंक्शन पर इनलाइन असेंबली का उपयोग करने का कोई कारण नहीं दिख रहा है (जो आपको विजुअल स्टूडियो पर x64 से संकलित करने में समस्याएं देगा जो इनलाइन असेंबली का समर्थन नहीं करता है)।

2

जैसा कि अन्य ने देखा है, आपको QueryPerformanceCounter का उपयोग करना चाहिए।

लेकिन यदि आप वास्तव में असेंबलर का उपयोग करना चाहते हैं, तो सबसे अच्छा आंतरिक __rdtsc का उपयोग करना हो सकता है।

unsigned __int64 __declspec(naked) GetPentiumTimer() { 
    __asm { 
     rdtsc 
     ret 
    } 
} 

मेरी जानकारी विजुअल C++ के लिए किसी भी समारोह जो इनलाइन कोडांतरक वैसे भी उपयोग कर रहा है के लिए इनलाइन करने के लिए इंकार कर रहा है:

क्या आप आंतरिक उपयोग करना चाहते हैं न, तो यह सबसे अच्छा aproach होगा। __declspec (नग्न) का उपयोग करके आप संकलक को सही ढंग से रजिस्टर उपयोग से निपटने के लिए कहेंगे।

लेकिन आंतरिक का उपयोग करना सबसे अच्छी बात होगी, इस तरह संकलक को पता चलेगा कि कौन से रजिस्टरों का उपयोग किया जाता है और यह उचित तरीके से रेखांकित किया गया है।

1

0F 31, जो आरडीटीएससी निर्देश है, अभी भी कोड के छोटे टुकड़ों के प्रदर्शन को मापने के लिए उपयोगी हो सकता है। I3 CPUs के लिए भी। यदि कार्य स्विचिंग के प्रभाव और थ्रेड को अलग-अलग कोर पर माइग्रेट करने से आपको परेशान नहीं होता है, तो RDTSC का उपयोग करना ठीक है। कई मामलों में आपको सीपीयूआईडी के साथ सीरियलाइजेशन को मजबूर करने के लिए अधिक सटीक परिणाम मिलते हैं।

आपके माप के लिए, यह काफी संभव है कि गलत तरीके से एसएसई i3 पर तेजी से काम कर रहा है। नवीनतम इंटेल प्रोसेसर (नेहलेम और सैंडी ब्रिज आर्किटेक्चर) गलत तरीके से मिसाल वाले मेमोरी ऑपरेंड को संभाल सकते हैं। निश्चित रूप से, वे कभी भी गठबंधन निर्देशों का प्रदर्शन नहीं करेंगे, लेकिन यदि कुछ अन्य कारक आपके परीक्षणों में प्रदर्शन को प्रभावित करते हैं, तो गठबंधन निर्देश धीमे काम करने लगते हैं।

संपादित करें:

देखें http://www.agner.org/optimize/#testp। यह आरडीटीएससी निर्देश उपयोग का एक अच्छा उदाहरण है।

0

QueryPerformanceCounter() विंडोज पर उच्च आवृत्ति टाइमर प्राप्त करने का सबसे आसान तरीका है। हालांकि, इसमें थोड़ा अधिक ओवरहेड है, क्योंकि यह एक सिस्टम कॉल — और frac12 के बारे में है; μ एस। यदि आप बहुत तेजी से घटनाओं का समय कर रहे हैं, या बहुत उच्च परिशुद्धता की आवश्यकता है तो यह एक समस्या हो सकती है।

यदि आपको 250 से अधिक नैनोसेकंद परिशुद्धता की आवश्यकता है, तो आप सीधे हार्डवेयर काउंटर प्राप्त करने के लिए the rdtsc intrinsic का उपयोग कर सकते हैं। यह मेरे i7 पर विलंबता के बारे में 10ns है।

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