मैं एक ऐसा प्रोग्राम तैयार कर रहा हूं जिसे अल्ट्रा-फास्ट होना चाहिए। यह सीयूडीए का उपयोग कर जीपीयू पर कुछ सामान चला रहा है और बाद में यह सीपीयू पर कुछ गणना करता है। इसके लिए, मुझे अत्यधिक अनुकूलित जीपीयू-डेटास्ट्रक्चर को उस चीज़ पर परिवर्तित करने की आवश्यकता है जिसे मैं आसानी से सीपीयू पर उपयोग कर सकता हूं। मेरा डेटा मूल रूप से एक ग्रिड में एक ग्राफ रखा गया है। वर्तमान में मैं सीपीयू भाग के लिए std :: वेक्टर का उपयोग कर रहा हूं।std :: वेक्टर बनाम सामान्य सरणी
new_graph.resize(blockSize * blockSize);
for (unsigned long long y = 0; y < blockSize; y++) {
for (unsigned long long x = 0; x < blockSize; x++) {
int idx = y * blockSize + x;
new_graph[idx] = Vertex(x, y);
}
}
बाद में: क्योंकि मैं जानता हूँ कि वहाँ काफी एक ओवरहेड है अगर मैं push_back()
रों का एक बहुत करते हैं और मैं कम से कम क्योंकि मैं जानता हूँ कि कितने कोने मैं अपने ग्राफ में है पता है, मैं अब इस के लिए निम्नलिखित कोड का उपयोग मैं किनारों को जोड़ता हूँ। दुर्भाग्यवश मुझे नहीं पता कि मेरे पास प्रति चरम कितने किनारे हैं, लेकिन मुझे पता है कि यह कभी भी 8 से बड़ा नहीं होगा। इसलिए मैं प्रत्येक std :: वेक्टर में reserve()
8 जो किनारों के लिए उपयोग करता हूं।
हालांकि, यह दोनों बेहद धीमे प्रतीत होते हैं। यदि मैं ग्राफ के लिए एक सामान्य सरणी का उपयोग करता हूं (इसलिए मूल रूप से बाहरी std :: वेक्टर को प्रतिस्थापित करना), उस भाग में गति सुधार बहुत बड़ा है (जैसे 10x या तो)।
ग्राफ के लिए यह करने योग्य है, लेकिन किनारों के लिए वास्तव में नहीं, क्योंकि मैं इन किनारों पर कुछ पोस्ट-प्रोसेसिंग करता हूं और इसके लिए मुझे वास्तव में std :: वेक्टर की तरह कुछ चाहिए जो थोड़े गतिशील है (मैं कुछ किनारों को जोड़ता हूं) ।
वर्तमान में डेटा को std :: vector में कनवर्ट करना GPU (जो एक स्मार्ट एमएसटी एल्गोरिदम है) पर मेरे एल्गोरिदम चलाने से 10 गुना धीमा है। यह वास्तव में मैं नहीं चाहता हूं, क्योंकि अब ओवरहेड रास्ता बहुत बड़ा है।
क्या कोई जानता है कि क्या हो रहा है या मैं इसे कैसे ठीक कर सकता हूं?
पेज। मैं -ओ 2 के साथ संकलित करता हूं, क्योंकि मुझे पहले ही पता चला है कि इससे बड़ा अंतर हो सकता है। ओओ 3 के साथ भी कोशिश की, कोई वास्तविक अंतर नहीं।
वर्टेक्स इस प्रकार परिभाषित किया गया है:
struct Pos {
int x, y;
Pos() {
x = 0;
y = 0;
}
Pos(int x, int y) {
this->x = x;
this->y = y;
}
};
struct Vertex {
Pos pos;
bool hidden;
unsigned long long newIdx;
Vertex() {
this->pos = Pos();
this->hidden = false;
this->numEdges = 0;
this->numRemovedEdges = 0;
}
Vertex(Pos &pos) {
this->pos = pos;
this->hidden = false;
this->numEdges = 0;
this->numRemovedEdges = 0;
}
Vertex(int x, int y) {
this->pos = Pos(x, y);
this->hidden = false;
this->numEdges = 0;
this->numRemovedEdges = 0;
}
int numEdges;
int numRemovedEdges;
std::vector<Edge> edges;
std::vector<bool> removed;
std::vector<bool> doNotWrite;
};
'-O3' के साथ संकलित करने का प्रयास करें जो कुछ फ़ंक्शंस को रेखांकित करेगा (99.9 99% मौका यह 'push_back' इनलाइन करेगा, और यदि यह तब नहीं होता है तो कार्यान्वयन या कंपाइलर बकवास का एक टुकड़ा है)। –
@daknok_t ने भी कोशिश की, कोई वास्तविक अंतर नहीं। – nickygerritsen
'आकार बदलें' के बजाय 'रिजर्व' को कॉल करना और फिर '[]' के बजाय 'push_back' का उपयोग करना 'आकार बदलें' द्वारा किए गए अनावश्यक प्रारंभिकरण से बच जाएगा। मुझे नहीं पता कि यह 10x मंदी का कारण है (मुझे संदेह है कि यह सब कुछ के लिए खाता है), लेकिन यह निश्चित रूप से मदद करनी चाहिए। –