2011-08-07 9 views
17

टेस्ट कोड:std :: sin() और std :: cos() पाप() और cos() से धीमा क्यों है?

$ g++ main.cc -o main 
$ time ./main 
a 
b 

real 0m1.406s 
user 0m1.370s 
sys  0m0.030s 

using namespace std; जोड़ने के बाद, समय आ गया है:

$ g++ main.cc -o main 
$ time ./main 
a 
b 

real 0m8.743s 
user 0m8.680s 
sys  0m0.030s 

संकलक:

$ g++ --version 
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2 
#include <cmath> 
#include <cstdio> 

const int N = 4096; 
const float PI = 3.1415926535897932384626; 

float cosine[N][N]; 
float sine[N][N]; 

int main() { 
    printf("a\n"); 
    for (int i = 0; i < N; i++) { 
     for (int j = 0; j < N; j++) { 
      cosine[i][j] = cos(i*j*2*PI/N); 
      sine[i][j] = sin(-i*j*2*PI/N); 
     } 
    } 
    printf("b\n"); 
} 

यहाँ समय हैविधानसभा:

Dump of assembler code for function [email protected]:          
0x0000000000400500 <+0>:  jmpq *0x200b12(%rip)  # 0x601018 <_GLOBAL_OFFSET_TABLE_+48> 
0x0000000000400506 <+6>:  pushq $0x3          
0x000000000040050b <+11>: jmpq 0x4004c0         
End of assembler dump. 

Dump of assembler code for function std::sin(float):        
0x0000000000400702 <+0>:  push %rbp          
0x0000000000400703 <+1>:  mov %rsp,%rbp         
0x0000000000400706 <+4>:  sub $0x10,%rsp        
0x000000000040070a <+8>:  movss %xmm0,-0x4(%rbp)       
0x000000000040070f <+13>: movss -0x4(%rbp),%xmm0       
0x0000000000400714 <+18>: callq 0x400500 <[email protected]>      
0x0000000000400719 <+23>: leaveq           
0x000000000040071a <+24>: retq            
End of assembler dump. 

Dump of assembler code for function [email protected]:         
0x0000000000400500 <+0>:  jmpq *0x200b12(%rip)  # 0x601018 <_GLOBAL_OFFSET_TABLE_+48> 
0x0000000000400506 <+6>:  pushq $0x3          
0x000000000040050b <+11>: jmpq 0x4004c0         
End of assembler dump. 
+11

@ नवाज: यह हो सकता है। यह एक कार्यान्वयन विवरण है कि '' वैश्विक नामस्थान में 'डबल पाप (डबल)' और 'डबल कॉस (डबल)' प्रदान करता है। ' 'और' printf' के लिए Ditto। –

+0

@ नवाज यह संकलित करता है। यह मेरा असली कोडिंग है। – rynlbrwn

+0

इस तरह के मुद्दों का उत्तर देने का सबसे आसान तरीका संकलक के असेंबली आउटपुट की तुलना करना है। –

उत्तर

19

आप एक अलग अधिभार का उपयोग कर रहे:

प्रयास करें

 double angle = i*j*2*PI/N; 
     cosine[i][j] = cos(angle); 
     sine[i][j] = sin(angle); 

इसके साथ या using namespace std;

+0

आपका कोड काम करता है, लेकिन यह नामस्थान परिवर्तन के साथ या उसके बिना तेज़ी से चलता है। मेरे द्वारा प्रदान किया गया कोड बहुत धीमा क्यों चलाता है? – rynlbrwn

+11

@Ryan: क्योंकि मेरा कोड हमेशा 'डबल पाप (डबल)' कहता है। आपका मूल कोड वैश्विक दायरे से 'डबल पाप (डबल)' या 'नामस्थान std' से' फ्लोट पाप (फ्लोट) 'कहता है। आधुनिक एफपीयू को युगल पर संचालन के लिए अनुकूलित किया गया है। –

+0

कुछ असेंबली जोड़ा गया, क्या आपका निष्कर्ष अभी भी है? (मैं कोई असेंबली निंजा नहीं हूं) – rynlbrwn

3

के बिना एक ही प्रदर्शन करना चाहिए मैं लगता अंतर यह है कि फ्लोट के लिए std :: sin() के लिए अधिभार हैं आर डबल, जबकि पाप() केवल डबल लेता है। फ्लोट के लिए std :: sin() के अंदर, डबल में रूपांतरण हो सकता है, फिर डबल्स के लिए std :: sin() पर कॉल किया जा सकता है, और फिर परिणाम का रूपांतरण वापस फ्लोट करने के लिए, इसे धीमा कर देता है।

+0

'फ्लोट' और 'डबल' के बीच रूपांतरण इसके लिए जिम्मेदार नहीं है। मैंने g ++ के साथ आज कुछ परीक्षण चलाए और पाया कि '-O2' 'फ्लोट' कोड का उपयोग करते समय बहुत धीमी थी।हालांकि, जब मैंने मैन्युअल रूपांतरणों के साथ परीक्षण किया, तो इस तरह: '(फ्लोट) पाप ((डबल) इनपुट)' मैंने पाया कि अनुकूलित 'फ्लोट' कोड अनुकूलित 'डबल' कोड से _faster_ चला गया, भले ही मैं ' 'डबल' 'sin' फ़ंक्शन का उपयोग करने के लिए फ़्लोट 'कोड। –

+0

@KyleA: वह 2011 था। अब 2017 है। रनटाइम कोड बदल सकता है। –

1

कंपाइलर कमांड लाइन में -एस ध्वज का उपयोग करें और असेंबलर आउटपुट के बीच अंतर की जांच करें। शायद using namespace std; निष्पादन योग्य फ़ाइल में बहुत सारी अप्रयुक्त सामग्री प्रदान करता है।

+0

यही कारण है कि मेरे पास प्रिंट स्टेटमेंट थे, ताकि यदि आप कोड चलाते हैं तो आप देख सकते हैं कि ज्यादातर समय लूप में बिताया जाता है, प्रारंभिक नहीं। – rynlbrwn

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