ऑप्टिमाइज़ेशन को चालू करने के साथ त्वरित परीक्षण करना, मुझे एक प्राचीन एएमडी 64 एक्स 2 प्रोसेसर के लिए लगभग 150 एमएस और एक उचित हाल ही में इंटेल i7 प्रोसेसर के लिए लगभग 9 0 एमएस का परिणाम मिला।
फिर मैंने एक कारण के बारे में कुछ विचार देने के लिए कुछ और किया जो आप सी ++ का उपयोग करना चाहेंगे। मैं पाश के चार पुनरावृत्तियों, इस पाने के लिए unrolled:
#include <stdio.h>
#include <ctime>
int main() {
double a = 3.1415926, b = 2.718;
double c = 0.0, d=0.0, e=0.0;
int i, j;
clock_t start, end;
for(j=0; j<10; j++) {
start = clock();
for(i=0; i<100000000; i+=4) {
a += b;
c += b;
d += b;
e += b;
}
a += c + d + e;
end = clock();
printf("Time Cost: %fms\n", (1000.0 * (end - start))/CLOCKS_PER_SEC);
}
printf("a = %lf\n", a);
return 0;
}
यह सी ++ 44ms के बारे में एएमडी पर में कोड को चलने देने के (इंटेल पर इस संस्करण को चलाने के लिए भूल गया)। तब मैंने कंपाइलर के ऑटो-वेक्टरिज़र (-कपर + वीसी ++ के साथ) चालू कर दिया। इससे थोड़ी और समय कम हो गई, एएमडी पर लगभग 40 एमएस और इंटेल पर 30 एमएस कम हो गया।
नीचे पंक्ति: यदि आप सी ++ का उपयोग करना चाहते हैं, तो आपको वास्तव में संकलक का उपयोग करने का तरीका सीखना होगा। यदि आप वास्तव में अच्छे परिणाम प्राप्त करना चाहते हैं, तो आप शायद बेहतर कोड लिखना सीखना चाहते हैं।
मुझे जोड़ना चाहिए: मैंने जावास्क्रिप्ट के तहत एक संस्करण को अनलॉक लूप के साथ परीक्षण करने का प्रयास नहीं किया था। ऐसा करने से जेएस में भी एक समान (या कम से कम कुछ) गति सुधार प्रदान हो सकता है। व्यक्तिगत रूप से, मुझे लगता है कि जावास्क्रिप्ट को सी ++ से तुलना करने से कोड को तेज़ बनाना बहुत दिलचस्प है।
यदि आप इस तरह के कोड को तेजी से चलाने के लिए चाहते हैं, तो लूप को अनलोल करें (कम से कम सी ++ में)।
समानांतर कंप्यूटिंग के विषय के बाद से, मैंने सोचा कि मैं ओपनएमपी का उपयोग करके एक और संस्करण जोड़ूंगा। जब मैं उस पर था, मैंने कोड को थोड़ा सा साफ़ कर दिया, इसलिए मैं क्या चल रहा था इसका ट्रैक रख सकता था। मैंने भीतरी कोड को थोड़ा सा बदल दिया, आंतरिक लूप के प्रत्येक निष्पादन के लिए समय के बजाय समग्र समय प्रदर्शित करने के लिए। जिसके परिणामस्वरूप कोड इस तरह देखा:
#include <stdio.h>
#include <ctime>
int main() {
double total = 0.0;
double inc = 2.718;
int i, j;
clock_t start, end;
start = clock();
#pragma omp parallel for reduction(+:total) firstprivate(inc)
for(j=0; j<10; j++) {
double a=0.0, b=0.0, c=0.0, d=0.0;
for(i=0; i<100000000; i+=4) {
a += inc;
b += inc;
c += inc;
d += inc;
}
total += a + b + c + d;
}
end = clock();
printf("Time Cost: %fms\n", (1000.0 * (end - start))/CLOCKS_PER_SEC);
printf("a = %lf\n", total);
return 0;
}
प्राथमिक इसके अलावा यहां निम्नलिखित (वैसे कुछ हद तक रहस्यमय) लाइन है:
#pragma omp parallel for reduction(+:total) firstprivate(inc)
इस संकलक बताता है एक से अधिक थ्रेड में बाहरी पाश निष्पादित करने के लिए एक साथ, प्रत्येक थ्रेड के लिए inc
की अलग प्रति, और समांतर अनुभाग के बाद total
के व्यक्तिगत मानों को एक साथ जोड़ना।
परिणाम इस बारे में है कि आप शायद क्या उम्मीद करेंगे। यदि हम कंपाइलर के -openmp
ध्वज के साथ ओपनएमपी को सक्षम नहीं करते हैं, तो रिपोर्ट समय लगभग 10 गुणा है जिसे हमने पहले व्यक्तिगत निष्पादन के लिए देखा था (एएमडी के लिए 40 9 एमएस, इंटेल के लिए 323 एमएस)। ओपनएमपी चालू होने के साथ, एएमडी के लिए समय 217 एमएस और इंटेल के लिए 100 एमएस तक गिर जाता है।
तो, इंटेल पर मूल संस्करण ने बाहरी लूप के एक पुनरावृत्ति के लिए 9 0 मिमी लिया। इस संस्करण के साथ हम बाहरी लूप के सभी 10 पुनरावृत्तियों के लिए थोड़ी देर (100 एमएस) प्राप्त कर रहे हैं - लगभग 9: 1 की गति में सुधार। अधिक कोर वाले मशीन पर, हम और भी सुधार की उम्मीद कर सकते हैं (ओपनएमपी आमतौर पर सभी उपलब्ध कोरों का लाभ उठाएगा, हालांकि यदि आप चाहें तो थ्रेड की संख्या मैन्युअल रूप से ट्यून कर सकते हैं)।
नहीं, मैं बस g ++ xxx.cpp कमांड का उपयोग करता हूं। अनुकूलित करने के लिए मैं किस पैरामीटर का उपयोग करूं? मैं सीपीपी से काफी परिचित नहीं हूँ। – streaver91
कृपया '-O3 -ffast-Math' जोड़ें और देखें कि C++ समय के साथ क्या होता है। –
* "लंबे समय तक, मुझे हमेशा लगता है कि सी ++ जावास्क्रिप्ट से तेज़ होना चाहिए।" * आप समझते हैं कि जावास्क्रिप्ट इंजन आमतौर पर सी ++ – jamylak