आपका C++ कोड धीमा चल रहा है? अब हुड के नीचे झांकने का समय है
\n\nआपने C++ में एक बेहतरीन कोड लिखा है। कंपाइलेशन बिना किसी त्रुटि के हुआ, प्रोग्राम चलता है... लेकिन वह सुस्ती से काम कर रहा है। है न? मन करता है कि सब कुछ असेंबली में फिर से लिखें या तुरंत मल्टीथ्रेडिंग जोड़ें। जल्दबाजी न करें। संभवतः समस्या आर्किटेक्चर की नहीं, बल्कि कुछ 'हॉट' फंक्शंस की है जो 90% CPU समय खा रहे हैं।
\n\nLinux की दुनिया में हमारे पास C++ कोड प्रोफाइलिंग के लिए शक्तिशाली टूल्स का भंडार है। यह जादू नहीं, विज्ञान है। हम अनुमान नहीं लगाते, बल्कि मापते हैं। इस गाइड में मैं आपको चार व्यावहारिक तरीके दिखाऊंगा: त्वरित 'ऊपर से नज़र' से लेकर माइक्रो-बेंचमार्किंग तक। आप सीखेंगे कि Linux पर C++ को कैसे प्रोफाइल करें एक प्रो की तरह।
\n\nअनुमान क्यों बुरा है, और प्रोफाइलिंग क्यों अच्छी है
\n\nकोड में गोता लगाने से पहले, ऑप्टिमाइज़ेशन का सुनहरा नियम याद रखें: "जो मापा नहीं गया, उसे ऑप्टिमाइज़ न करें"। आपकी अंतर्ज्ञान एक बुरी सलाहकार है। अक्सर हम ऐसे फंक्शन को ऑप्टिमाइज़ करने में घंटों बिता देते हैं जो मिनट में एक बार कॉल होता है, और एक सामान्य 10 मिलियन इटरेशन वाले लूप को नज़रअंदाज कर देते हैं।
\n\nप्रोफाइलिंग तीन मुख्य सवालों के जवाब देती है:
\n- \n
- प्रोग्राम कहाँ सबसे अधिक समय बिता रहा है? \n
- ऐसा क्यों हो रहा है (अकुशल एल्गोरिदम, बहुत अधिक I/O ऑपरेशन, कैश मिस)? \n
- आपके बदलावों के बाद क्या बदला है? \n
आज हम चार ऐसे टूल्स पर चर्चा करेंगे जो आपके 99% काम आएंगे। चलिए शुरू करते हैं!
\n\nटूल #1: gprof — क्लासिक तरीका
\n\ngprof एक पुराना, भरोसेमंद, बिल्ट-इन GNU प्रोफाइलर है। यह दो चरणों में काम करता है: प्रोग्राम चलने के दौरान आंकड़े इकट्ठा करना और फिर उनका विश्लेषण करना। फायदे: कुछ अतिरिक्त इंस्टॉल करने की ज़रूरत नहीं, हर डिस्ट्रीब्यूशन में उपलब्ध। नुकसान: अनुमानित परिणाम देता है और मल्टीथ्रेडेड प्रोग्राम के साथ सीधे काम नहीं करता।
\n\ngprof का उपयोग कैसे करें
\n\nचरण 1. प्रोग्राम को विशेष फ्लैग -pg के साथ कंपाइल करें:
g++ -pg -O2 my_program.cpp -o my_program\n\nध्यान दें: हम -O2 का उपयोग कर रहे हैं। बिना ऑप्टिमाइज़ेशन के डीबग बिल्ड को प्रोफाइल करना व्यर्थ है, आपको गलत तस्वीर मिलेगी।
चरण 2. प्रोग्राम चलाएं। यह थोड़ा धीमा चलेगा क्योंकि gprof डेटा इकट्ठा कर रहा है।
\n./my_program\n\nचरण 3. वर्तमान फ़ोल्डर में gmon.out फ़ाइल बनेगी। इसका विश्लेषण करें:
gprof my_program gmon.out > analysis.txt\n\nanalysis.txt खोलें और कुछ इस तरह देखें:
Flat profile:\nEach sample counts as 0.01 seconds.\n % cumulative self self total\n time seconds seconds calls us/call us/call name\n 60.00 0.06 0.06 10000 6.00 6.00 slow_function\n 20.00 0.08 0.02 5000 4.00 4.00 fast_function\n 10.00 0.09 0.01 main\n\nवाह! हम देख सकते हैं कि slow_function ने 60% समय लिया। यह ऑप्टिमाइज़ेशन के लिए हमारा उम्मीदवार है।
प्रोफाइलिंग के लिए नमूना कोड
\n\nचलिए एक सरल प्रोग्राम लिखते हैं जिसे हम सभी टूल्स से प्रोफाइल करेंगे:
\n\n#include <iostream>\n#include <cmath>\n\nvoid slow_function(int n) {\n volatile double sum = 0.0; // volatile ताकि कंपाइलर इसे शून्य न करे\n for (int i = 0; i < n; ++i) {\n for (int j = 0; j < 1000; ++j) {\n sum += std::sin(i) * std::cos(j);\n }\n }\n std::cout << sum << std::endl;\n}\n\nvoid fast_function(int n) {\n volatile int count = 0;\n for (int i = 0; i < n; ++i) {\n count += i % 2;\n }\n std::cout << count << std::endl;\n}\n\nint main() {\n slow_function(10000);\n fast_function(50000);\n return 0;\n}\n\nइसे -pg फ्लैग के साथ कंपाइल करें और चलाएं