क्या फोरट्रान कंपाइलर वास्तव में सी कंपाइलर की तुलना में अधिक तेज़ कोड उत्पन्न करते हैं?


17

जब मैं विश्वविद्यालय में अध्ययन कर रहा था तो मैंने अक्सर यह विचार सुना कि फोरट्रान कंपाइलरों ने समतुल्य कार्यक्रम के लिए सी कंपाइलरों की तुलना में अधिक तेजी से कोड का उत्पादन किया।

मुख्य तर्क इस तरह से चला गया: एक फोरट्रान कंपाइलर प्रति लाइन की औसत 1,1 प्रोसेसर निर्देश पर निकलता है, जबकि एक सी कंपाइलर औसतन 1,6 प्रोसेसर निर्देश प्रति कोड की लाइन पर निकलता है - मुझे सटीक संख्या याद नहीं है लेकिन विचार यह था कि सी संकलक ने अधिक मशीन कोड का अनुकरण किया और इसलिए धीमी कार्यक्रमों का उत्पादन किया।

इस तरह की तुलना कितनी वैध है? क्या हम कह सकते हैं कि फोरट्रान कंपाइलर सी कंपाइलर या इसके विपरीत तेजी से प्रोग्राम बनाते हैं और यह अंतर क्यों होता है?


19
इसका सीधा सा मतलब यह हो सकता है कि फोरट्रान प्रोग्राम सी से अधिक क्रियात्मक हैं ... एक सार्थक तुलना केवल दोनों भाषाओं में समान कार्यक्षमता को लागू करने और परिणामस्वरूप मशीन कोड (आकार और गति) की तुलना करके की जा सकती है ।
पेटर टॉर्क

साथ ही, उत्पन्न कोड समानांतर निष्पादन का समर्थन करता है?

@ Péter Török, इसका सीधा सा मतलब यह है कि, कहते हैं, फोरट्रान में BLAS और LAPACK तब बेहतर प्रदर्शन करते थे, जब उनका कोई C / C ++ पोर्ट होता था। अब यह फासला कम होता जा रहा है।
एसके-तर्क

6
आप केवल यह तर्क दे सकते हैं कि एक कंपाइलर तेजी से कोड का उत्पादन करता है यदि आपके पास दोनों भाषाओं में 100% समतुल्य कार्यक्रम है, जो विशेषज्ञों द्वारा लिखे गए हैं जो अपने संकलक को जानते हैं और जो प्रदर्शन के लिए जिम्मेदार हो सकते हैं।
फाल्कन

पूर्व फोरट्रान ने पुनरावृत्ति का समर्थन नहीं किया और इस तरह जरूरी नहीं था कि स्टैक पर फ़ंक्शन कॉल तर्क को धक्का दिया जाए क्योंकि प्रत्येक कवक के तर्कों के लिए एक सांख्यिकीय रूप से आवंटित स्थान होगा। यह एक कारण है कि यह तेजी से हो सकता है। मुझे लगता है कि आपको यहां अधिक संपूर्ण उत्तर मिल सकता है: amazon.com/Programming-Language-Pragmatics-Third-Edition/dp/…
पेड्रो रोलो

जवाबों:


36

IIRC मुख्य कारणों में से एक है क्योंकि फोरट्रान को तेज कहा जाता है सूचक अलियासिंग की अनुपस्थिति है , इसलिए वे अनुकूलन का उपयोग कर सकते हैं जो सी संकलक उपयोग नहीं कर सकते हैं:

FORTRAN में, फ़ंक्शन तर्क एक दूसरे को उर्फ ​​नहीं कर सकते हैं, और संकलक मानता है कि वे नहीं करते हैं। यह उत्कृष्ट अनुकूलन को सक्षम करता है, और एक तेज भाषा के रूप में फोरट्रान की प्रतिष्ठा का एक प्रमुख कारण है। (ध्यान दें कि फोर्जिंग फ़ंक्शन के भीतर भी एलियासिंग हो सकता है। उदाहरण के लिए, यदि A एक सरणी है और i और j ऐसे इंडेक्स हैं जो समान मान वाले हैं, तो A [i] और A [j] ए के लिए दो अलग-अलग नाम हैं एक ही मेमोरी लोकेशन। सौभाग्य से, बेस ऐरे में समान नाम होना चाहिए, ऐसे मामलों का निर्धारण करने के लिए इंडेक्स विश्लेषण किया जा सकता है जहां ए [i] और ए [जे] उपनाम नहीं हो सकते।)

लेकिन मैं यहां दूसरों से सहमत हूं: कोड की एक पंक्ति के लिए उत्पन्न कोडांतरक निर्देशों की औसत संख्या की तुलना पूरी बकवास है। उदाहरण के लिए, एक आधुनिक x86 कोर समानांतर में दो निर्देशों को निष्पादित कर सकता है यदि वे समान रजिस्टरों का उपयोग नहीं करते हैं। तो आप (सिद्धांत में) उन्हें फिर से व्यवस्थित करके निर्देशों पर एक ही सेट के लिए 100% की प्रदर्शन वृद्धि हासिल कर सकते हैं । अच्छा संकलक भी अक्सर अधिक कोड प्राप्त करने के लिए अधिक विधानसभा निर्देश उत्पन्न करेगा (थिंक लूप अनरोलिंग, इनलाइनिंग)। कोड कोड के प्रदर्शन के बारे में कोडांतरक निर्देशों की कुल संख्या बहुत कम बताती है।


बेहतर अनुकूलन के लिए एक और कारण जटिल संख्या के लिए मूल समर्थन है।
तर्क

निश्चित रूप से फोरट्रान IV या के लिए सही है। सुनिश्चित नहीं हैं कि आधुनिक फोरट्रान में अभी भी पॉइंटर्स, डायनेमिक मेरी आदि नहीं हैं
इंगो

2
यही कारण है कि हम अक्सर खेल उद्योग में सी और सी ++ में विकसित होने पर इनलाइन असेंबली के एक बिट तक गिर जाते हैं। लोग अक्सर दावा कर सकते हैं कि उन्हें पसंद है कि "कंपाइलर विधानसभा लिखने वाले मनुष्यों की तुलना में बेहतर अनुकूलन कर सकते हैं", तथ्य यह है, सूचक अलियासिंग का मतलब है कि वे अक्सर नहीं कर सकते हैं । कोड हम हाथ से लिख सकते हैं संकलक के लिए तकनीकी रूप से अवैध होगा, यह जानते हुए भी कि यह सूचक एलियासिंग के बारे में कुछ नहीं करता है।
कार्सन 63000

5
सी का restrictकीवर्ड एक फ़ंक्शन के लेखक को यह निर्दिष्ट करने की अनुमति देता है कि एक पॉइंटर में कोई उपनाम नहीं है। क्या यह अंतर को संबोधित करने के लिए पर्याप्त है, या इसके लिए और भी बहुत कुछ है?
बी.के.

@bk: C की "प्रतिबंधित" हमले "आधी समस्या"; यह कहना संभव है कि एक विशिष्ट पॉइंटर अपने जीवनकाल के भीतर किसी अन्य चीज को नहीं बदलेगा, लेकिन संकलक को यह बताने का कोई तरीका नहीं है कि एक वस्तु जिसका पता किसी फ़ंक्शन को दिया गया था, उस फ़ंक्शन के वापस आने के बाद किसी भी चीज़ से अलियास नहीं किया जाएगा।
18

8

पूरी तरह से अमान्य तुलना।

सबसे पहले, जैसा कि @ Péter Török बताते हैं, आपको पहले फोरट्रान और सी से बराबर कार्यक्रमों में लाइनों की संख्या की तुलना करनी चाहिए , इसके लिए भी उत्पादित लाइनों की संख्या पर एक वैध तुलना हो।

दूसरा, कोड की कम लाइनें हमेशा तेज कार्यक्रमों के बराबर नहीं होती हैं । सभी मशीन निर्देशों को निष्पादित करने के लिए समान संख्या में चक्र नहीं लेते हैं , लेकिन आपके पास अन्य समस्याएं भी हैं जैसे कि मेमोरी एक्सेस , कैशिंग , आदि।

उसके शीर्ष पर, लंबी कोड रन तेजी से हो सकते हैं क्योंकि इसके परिणामस्वरूप निष्पादित लाइनों की कम संख्या होती है (यानी, लाइन गणना! = निष्पादित लाइन काउंट )।


5

दान सही है, लंबे कार्यक्रमों का मतलब धीमी कार्यक्रमों से नहीं है। यह बहुत निर्भर करता है कि वे क्या कर रहे हैं।

मैं फोरट्रान पर कोई विशेषज्ञ नहीं हूं, मैं थोड़ा जानता हूं। उनकी तुलना में, मुझे लगता है कि अच्छी तरह से लिखा गया सी, फोरट्रान की तुलना में अधिक जटिल डेटा संरचनाओं और कार्यक्षमता के साथ प्रदर्शन में बेहतर होगा। किसी ने (कृपया) मुझे सही कर दिया अगर मैं यहाँ गलत हूँ, लेकिन मुझे लगता है कि फोरट्रान सी की तुलना में 'निचले स्तर' पर कुछ हद तक है। यदि हां, तो मुझे यकीन है कि कुछ समस्याएं फोरट्रान पर तेजी से आएंगी।

एक और बात, पहली नज़र में मुझे लगा कि आप पूछ रहे हैं कि क्या कंपाइलर तेज़ हैं। मुझे वास्तव में लगता है कि फोरट्रान आमतौर पर समान मात्रा में कोड के लिए तेजी से संकलित करेगा, लेकिन परिणामी कार्यक्रम और यह कैसे चलता है यह एक अलग कहानी होगी। इसके माध्यम से पार्स करना सरल है।


2
यदि आप जटिल डेटा संरचनाओं का उपयोग कर रहे हैं तो FORTRAN शायद गलत विकल्प है। फोरट्रान को सरल संख्या में बहुत तेजी से क्रंच करने के लिए अनुकूलित किया गया है।
ज़ाचरी के

4

मुझे लगता है कि इसका एक हिस्सा यह है कि फोरट्रान कंपाइलरों को कुछ प्रकार के गणित को बहुत तेजी से करने के लिए डिज़ाइन किया गया है। जिस तरह से लोग फोरट्रान का उपयोग करते हैं, गणना करने के लिए जितनी जल्दी हो सके


4

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

कोड की पंक्तियाँ कोड के समान विवरण नहीं देती हैं। फोरट्रान के पहले के संस्करणों ने प्रति पंक्ति केवल एक कथन की अनुमति दी थी। फोरट्रान के बाद के संस्करण प्रति पंक्ति कई कथन ले सकते हैं। C में प्रति पंक्ति कई कथन हो सकते हैं। इंटेल के आईवीएफ (पूर्व में सीवीएफ, एमएस पावरस्टेशन) और इंटेल के सी जैसे तेज उत्पादन संकलक पर, वास्तव में दोनों के बीच कोई अंतर नहीं है। ये संकलक अत्यधिक अनुकूलित हैं।


4

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

फ़ंक्शन पर विचार करें:

void diff(float dest[], float src1[], float src2[], int n)
{
  for (int i=0; i<n; i++)
    dest[i] = src1[i] - src2[i];
}

यदि एक संकलक जानता था कि प्रत्येक बिंदु एक सरणी की शुरुआत की पहचान करेगा, तो यह कोड उत्पन्न कर सकता है जो समानांतर में सरणी के तत्वों पर या किसी भी क्रम में कार्य करेगा, क्योंकि किसी भी x =! y के लिए, गंतव्य पर संचालन [x! ] src1 [y] और न ही src2 [y] को प्रभावित नहीं करेगा। उदाहरण के लिए, कुछ प्रणालियों पर एक कंपाइलर कोड के बराबर उत्पन्न करने से लाभान्वित हो सकता है:

void dif(float dest[], float src1[], float src2[], int n)
{
  int i=0;
  float t1a,t1b,t2a,t2b,tsa,tsb;
  if (n > 2)
  {
    n-=4;
    t1a = src1[n+3]; t1b = src2[n+3]; t1b=src2[n+2]; t2b = src2[n+2];
    do
    {
      tsa = t1a-t2a;
      t1a = src1[n+1]; t2a = src2[n+1]; 
      tsb = t2b-t2b;
      dest[n+3] = tsa;
      t1b = src1[n]; t2b = src2[n]; 
      n-=2;
      dest[n+4] = tsb;
    } while(n >= 0);
    ... add some extra code to handle cleanup
  }
  else
    ... add some extra code to handle small values of n
}

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

जबकि एक सी प्रोग्रामर स्पष्ट रूप से बाहर कोड लिखने के द्वारा तुलनीय प्रदर्शन प्राप्त करने का प्रयास कर सकता है जो लूप को अनियंत्रित करता है और आसन्न पासों के संचालन को ओवरलैप करता है, ऐसे कोड आसानी से प्रदर्शन को नीचा दिखा सकते हैं यदि यह इतने सारे स्वचालित चर का उपयोग करता है कि एक कंपाइलर को उन्हें "फैलाना" पड़ता है। स्मृति। एक फोरट्रान कंपाइलर के ऑप्टिमाइज़र को संभवतः एक प्रोग्रामर से अधिक पता होगा कि इंटरलेविंग के कौन से रूप किसी दिए गए परिदृश्य में इष्टतम प्रदर्शन करेंगे, और इस तरह के निर्णय अक्सर ऐसे कंपाइलरों के लिए सबसे अच्छे होते हैं। C99 एक जोड़कर कुछ हद तक सी स्थिति में सुधार करने का प्रयास किया जबकि restrictक्वालीफायर, कि केवल यहां इस्तेमाल किया जा सकता है अगर dest[]दोनों से एक अलग सरणी था src1[]और src2[], या प्रोग्रामर लूप के अलग-अलग संस्करण मामलों में जहां सभी को संभालने के लिए कहा कि यदि destसे संबंध तोड़ना थाsrc1और src2, जहां src1[]और destसमान थे और src2असहमति थी, जहां src2[]और dest[]समान थे और src1असहमति थी, और जहां तीनों सरणियां समान थीं। इसके विपरीत, फोरट्रान समान स्रोत कोड और समान मशीन कोड का उपयोग करके कठिनाई के बिना सभी चार मामलों को संभाल सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.