मैं इस तरह एक वर्ग है:संरचना - प्रदर्शन अंतर
//Array of Structures
class Unit
{
public:
float v;
float u;
//And similarly many other variables of float type, upto 10-12 of them.
void update()
{
v+=u;
v=v*i*t;
//And many other equations
}
};
मैं इकाई प्रकार की वस्तुओं की एक सरणी पैदा करते हैं। और उन पर अद्यतन कॉल करें।
int NUM_UNITS = 10000;
void ProcessUpdate()
{
Unit *units = new Unit[NUM_UNITS];
for(int i = 0; i < NUM_UNITS; i++)
{
units[i].update();
}
}
आदेश चीज़ों को गति, और संभवतः पाश autovectorize करने के लिए, मैं सरणियों के संरचना करने के AOS बदल दिया।
//Structure of Arrays:
class Unit
{
public:
Unit(int NUM_UNITS)
{
v = new float[NUM_UNITS];
}
float *v;
float *u;
//Mnay other variables
void update()
{
for(int i = 0; i < NUM_UNITS; i++)
{
v[i]+=u[i];
//Many other equations
}
}
};
जब लूप ऑटोवेक्टरिज़ करने में विफल रहता है, तो मुझे सरणी की संरचना के लिए बहुत खराब प्रदर्शन मिल रहा है। 50 इकाइयों के लिए, एसओए का अपडेट एओएस की तुलना में थोड़ा तेज है। लेकिन फिर 100 इकाइयों से, एसओए एओएस की तुलना में धीमी है। 300 इकाइयों पर, सोए लगभग दोगुनी है। 100K इकाइयों पर, एसओए एओएस की तुलना में 4x धीमी है। जबकि कैश सोए के लिए एक मुद्दा हो सकता है, मुझे उम्मीद नहीं थी कि प्रदर्शन अंतर यह उच्च होगा। कैशग्रींड पर प्रोफाइलिंग दोनों दृष्टिकोणों के लिए समान संख्या में मिस दिखाती है। यूनिट ऑब्जेक्ट का आकार 48 बाइट्स है। एल 1 कैश 256 के है, एल 2 1 एमबी है और एल 3 8 एमबी है। मुझे यहां क्या समझ नहीं आ रहा है? क्या यह वास्तव में एक कैश मुद्दा है?
संपादित करें: मैं जीसीसी 4.5.2 का उपयोग कर रहा हूँ। कंपाइलर विकल्प -o3 -msse4 -ftree-vectorize हैं।
मैंने सोए में एक और प्रयोग किया। गतिशील रूप से सरणी आवंटित करने के बजाय, मैंने संकलन समय में "v" और "u" आवंटित किया। जब 100K इकाइयां होती हैं, तो यह एक प्रदर्शन देता है जो गतिशील रूप से आवंटित सरणी के साथ सोए से 10x तेज होता है। यहाँ क्या हो रहा है? स्थैतिक और गतिशील आवंटित स्मृति के बीच ऐसा प्रदर्शन अंतर क्यों है?
इसे बनाने के लिए आप किस कंपाइलर विकल्प का उपयोग करते हैं? –
यह सुनिश्चित नहीं है कि इससे कोई फर्क पड़ता है, लेकिन [std :: valarray] (http://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a00738.html) हो सकता है (या हो सकता है) मदद। यह पूरे सरणी (इस तरह के क्लीनर सिंटैक्स) पर गणितीय परिचालन करने के लिए डिज़ाइन किया गया है, लेकिन मुझे लगता है कि कार्यान्वयनकर्ताओं के पास उन परिचालनों को अनुकूलित करने और बुद्धिमान आवंटन आदि को संभव बनाने के लिए विशेष ओवरलोड होते हैं। यह बिल्कुल मदद नहीं कर सकता है, लेकिन एक लायक हो सकता है। – pstrjds
जब आप बेंचमार्क चलाने से पहले डेटासेट को शून्य करते हैं तो क्या होता है? अनियंत्रित फ्लोटिंग-पॉइंट [denormalized] होने का एक उच्च अवसर है (http://stackoverflow.com/a/9314926/922184)। आप नहीं चाहते कि वह आपके बेंचमार्क को खराब कर दे। – Mysticial