/ / बहु-आयाम सरणी और एकल सरणी के बीच डेटा संग्रहीत करने का सबसे कुशल तरीका क्या है? - सी #, सरणियाँ, बहुआयामी-सरणी, एकता 3 डी, दांतेदार-सरणियाँ

बहु-आयाम सरणी और एक सरणी के बीच डेटा संग्रहीत करने का सबसे प्रभावी तरीका क्या है? - सी #, सरणी, बहुआयामी-सरणी, unity3d, jagged-arrays

अनिवार्य रूप से मुझे यकीन नहीं है कि सबसे तेज़ पहुंच के लिए 3 डी डेटा संरचना को कैसे स्टोर किया जाए क्योंकि मुझे यकीन नहीं है कि बहु-आयामी सरणियों के लिए हुड के नीचे क्या चल रहा है।

नोट: सरणियाँ प्रत्येक और हर बार एक स्थिर और ज्ञात आकार होगी, और प्रत्येक तत्व ठीक 16 बिट्स होगा।

विकल्प एक में एक बहु-आयाम सरणी है data[16, 16, 16] और बस के माध्यम से उपयोग data[x, y, z] विकल्प दो में एक एकल आयाम सरणी है data[16 * 16 * 16] और के माध्यम से उपयोग data[x + (y * 16) + (z * 16 * 16)].

जैसा कि प्रत्येक तत्व केवल 16 बिट लंबा होना चाहिए, औरमुझे संदेह है कि एक बहु-आयाम सरणी अन्य सरणियों के बहुत सारे संदर्भों को आंतरिक रूप से कम से कम 32 बिट्स प्रति एक स्टोर करेगी, जो कि बहुत सारी व्यर्थ मेमोरी है। हालांकि, मुझे डर है कि यह विकल्प दो बार हर बार निर्दिष्ट समीकरण को चलाने की तुलना में तेज हो सकता है, और गति इस परियोजना के लिए महत्वपूर्ण है।

तो, क्या कोई मुझे बता सकता है कि स्मृति की खपत में अंतर की तुलना में गति में कितना अंतर होगा?

उत्तर:

जवाब के लिए 3 № 1

C # मेमोरी के सिंगल ब्लॉक के रूप में बहुआयामी सरणियों को संग्रहीत करता है, इसलिए वे लगभग एक ही चीज को संकलित करते हैं। (एक अंतर यह है कि जाँच करने के लिए सीमा के तीन सेट हैं)।

अर्थात। arr[x,y,z] के बराबर है arr[x + y*ny +z*nz*ny] और आम तौर पर समान प्रदर्शन विशेषताओं होंगे।

हालाँकि, सटीक प्रदर्शन मेमोरी एक्सेस के पैटर्न पर हावी होगा, और यह कैसे कैश सुसंगतता (कम से कम बड़ी मात्रा में डेटा के लिए) को प्रभावित करता है। आप पा सकते हैं कि नेस्टेड छोरों पर x, फिर y फिर z यदि प्रोसेसर कैश में वर्तमान में उपयोग किए गए डेटा को रखने का बेहतर काम करता है, तो एक अलग क्रम में छोरों को करने की तुलना में तेज या धीमा हो सकता है।

यह सटीक एल्गोरिदम पर अत्यधिक निर्भर है, इसलिए यह एक उत्तर देना संभव है जो सभी एल्गोरिदम के लिए सही है।

किसी भी गति में कमी बनाम सी का दूसरा कारणया C ++ सीमा-जाँच है, जिसकी आवश्यकता अभी भी एक आयामी सरणी मामले में होगी। हालांकि ये अक्सर होगा, लेकिन हमेशा नहीं, स्वचालित रूप से हटा दिया जाएगा।

फिर से, सटीक एल्गोरिदम प्रभावित करेगा कि क्या अनुकूलक सीमा की जाँच को हटाने में सक्षम है।

आपकी कार्रवाई इस प्रकार होनी चाहिए:

  • एल्गोरिथ्म के एक भोले संस्करण के साथ लिखें arr[x,y,z].
  • अगर यह है काफी तेज़ आप रुक सकते हो।
  • अन्यथा यह जांचने के लिए एल्गोरिथ्म को प्रोफाइल करें कि यह वास्तव में एरे एक्सेस है जो कि इश्यू हैं, मेमोरी एक्सेस पैटर्न आदि का विश्लेषण करते हैं।

जवाब के लिए 3 № 2

मुझे लगता है कि यह इंगित करने के लायक है कि यदि आपके सरणी आयाम वास्तव में सभी 16 हैं, तो आप सरणी के लिए सूचकांक (x, y, z) से बहुत अधिक कुशलता से गणना कर सकते हैं:

int index = x | y << 4 | z << 8;

और उलटा:

int x = index & 0xf;
int y = (index >> 4) & 0xf;
int z = (index >> 8) & 0xf;

यदि यह मामला है, तो मैं एकल-आयामी सरणी का उपयोग करने की सलाह देता हूं क्योंकि यह लगभग निश्चित रूप से तेज होगा।

ध्यान दें कि यह पूरी तरह से संभव है कि जेआईटी संकलक इस अनुकूलन को वैसे भी निष्पादित करेगा (यह मानते हुए कि गुणा आपके ओपी के अनुसार कठिन-कोडित है), लेकिन यह स्पष्ट रूप से करने के लायक है।

कारण यह है कि मैं कहता हूं कि एकल-आयामी सरणी अधिक तेज़ होगी क्योंकि नवीनतम संकलक में बहु-आयामी सरणी पहुंच के लिए कुछ अनुकूलन की कमी है, जैसा कि इस धागे में चर्चा की गई है.

उस ने कहा, आपको यह देखना चाहिए कि वास्तव में सबसे तेज क्या है।

जैसा कि एरिक लिपर्ट कहते हैं: "यदि आप जानना चाहते हैं कि कौन सा घोड़ा तेज है, तो अपने घोड़ों की दौड़ करें".


उत्तर № 3 के लिए 1

मैं एकल-प्रवण सरणी के लिए मतदान करूंगाज्यादा तेजी से काम करना चाहिए। मूल रूप से आप कुछ परीक्षण लिख सकते हैं, अपने सबसे सामान्य कार्यों का प्रदर्शन कर सकते हैं और खर्च किए गए समय को माप सकते हैं। यदि आपके पास 2 ^ n सरणी आकार है, तो गुणन के बजाय बाएं शिफ्ट ऑपरेशन का उपयोग करके तत्व स्थिति तक पहुंचना बहुत तेज़ है।