डेटा उन्मुख डिजाइन क्या है?


156

मैं इस लेख को पढ़ रहा था , और यह आदमी इस बारे में बात कर रहा है कि कैसे ओओपी के साथ डेटा उन्मुख डिजाइन में मिश्रण करने से सभी को बहुत फायदा हो सकता है। हालांकि, वह कोई भी कोड नमूने नहीं दिखाता है।

मैंने इसे देखा और किसी भी वास्तविक जानकारी को नहीं पाया कि यह क्या है, अकेले किसी भी कोड के नमूने दें। क्या कोई इस शब्द से परिचित है और एक उदाहरण दे सकता है? क्या यह शायद किसी और चीज़ के लिए एक अलग शब्द है?


7
गेम डेवलपर का वह लेख अब ब्लॉग रूप में पढ़ने में आसान है: gamesfromwithin.com/data-oriented-design
Edmundito

58
क्या आप लोगों ने कभी कुछ गुगली की है, एक अच्छा लक्षित SO प्रश्न पाया है, और फिर यह महसूस किया कि क्या आप इसे सालों पहले पूछा था?
16


14
@ryeguy, मेरे पास एक सवाल था, इसे googled, एक अच्छा SO प्रश्न मिला, और फिर एहसास हुआ कि मैंने वर्षों पहले इसका उत्तर दिया था।
माइकल डियरडफ

4
मैं कुछ googled और एक अच्छा तो सवाल मिला और लगता है क्या? यह न तो मैं था जिसने पूछा और न ही उत्तर दिया :)
नदजीब ममी

जवाबों:


288

सबसे पहले, डेटा चालित डिज़ाइन के साथ इसे भ्रमित न करें।

डेटा ओरिएंटेड डिज़ाइन के बारे में मेरी समझ यह है कि यह कुशल प्रोसेसिंग के लिए आपके डेटा को व्यवस्थित करने के बारे में है। विशेष रूप से कैश मिसेज आदि के संबंध में। दूसरी ओर डेटा ड्रिवेन डिज़ाइन आपके प्रोग्राम व्यवहार के बहुत सारे नियंत्रण को बताने के बारे में है ( एंड्रयू कीथ के उत्तर द्वारा बहुत अच्छी तरह से वर्णित है )।

कहते हैं कि आपके आवेदन में रंग, त्रिज्या, बंधुत्व, स्थिति आदि गुणों के साथ आपके पास गेंद की वस्तुएं हैं।

ऑब्जेक्ट ओरिएंटेड दृष्टिकोण

OOP में आप इस तरह गेंदों का वर्णन करेंगे:

class Ball {
  Point  position;
  Color  color;
  double radius;

  void draw();
};

और फिर आप इस तरह गेंदों का एक संग्रह बनाएंगे:

vector<Ball> balls;

डेटा ओरिएंटेड दृष्टिकोण

डेटा ओरिएंटेड डिज़ाइन में, हालांकि, आपको इस तरह कोड लिखने की अधिक संभावना है:

class Balls {
  vector<Point>  position;
  vector<Color>  color;
  vector<double> radius;

  void draw();
};

जैसा कि आप देख सकते हैं कि अब एक बॉल का प्रतिनिधित्व करने वाली कोई एकल इकाई नहीं है। बॉल ऑब्जेक्ट केवल निहित रूप से मौजूद हैं।

इसके कई फायदे हो सकते हैं, प्रदर्शन के हिसाब से। आमतौर पर हम एक ही समय में कई गेंदों पर ऑपरेशन करना चाहते हैं। हार्डवेयर आम तौर पर कुशलता से संचालित करने के लिए स्मृति की बड़ी निरंतर मात्रा चाहते हैं।

दूसरी बात यह है कि आप ऐसे ऑपरेशन कर सकते हैं जो केवल गेंदों के गुणों के हिस्से को प्रभावित करते हैं। उदाहरण के लिए, यदि आप सभी गेंदों के रंगों को विभिन्न तरीकों से जोड़ते हैं, तो आप चाहते हैं कि आपके कैश में केवल रंग की जानकारी हो। हालाँकि जब सभी बॉल प्रॉपर्टीज को एक यूनिट में स्टोर किया जाता है तो आप बॉल के अन्य सभी प्रॉपर्टी में भी खींच लेंगे। हालांकि आपको उनकी जरूरत नहीं है।

कैश उपयोग उदाहरण

कहते हैं कि प्रत्येक गेंद 64 बाइट्स लेती है और एक पॉइंट 4 बाइट्स लेता है। एक कैश स्लॉट कहता है, 64 बाइट्स भी। अगर मैं 10 गेंदों की स्थिति को अपडेट करना चाहता हूं, तो मुझे 10 * 64 = 640 बाइट्स की मेमोरी को कैश में खींचना होगा और 10 कैशे को प्राप्त करना होगा। हालांकि अगर मैं गेंदों की स्थिति को अलग-अलग इकाइयों के रूप में काम कर सकता हूं, तो यह केवल 4 * 10 = 40 बाइट लेगा। यह एक कैशे में फिट बैठता है। इस प्रकार हम सभी 10 गेंदों को अपडेट करने के लिए केवल 1 कैश मिस करते हैं। ये संख्या मनमानी है - मुझे लगता है कि कैश ब्लॉक बड़ा है।

लेकिन यह दिखाता है कि मेमोरी लेआउट कैश हिट और इस तरह के प्रदर्शन पर गंभीर प्रभाव डाल सकता है। यह केवल महत्व में वृद्धि करेगा क्योंकि सीपीयू और रैम की गति के बीच का अंतर चौड़ा होता है।

मेमोरी को कैसे लेआउट करें

अपने बॉल उदाहरण में मैंने इस मुद्दे को बहुत सरल कर दिया है, क्योंकि आमतौर पर किसी भी सामान्य ऐप के लिए आप एक साथ कई चर का उपयोग करेंगे। उदाहरण के लिए स्थिति और त्रिज्या का उपयोग अक्सर एक साथ किया जाएगा। तब आपकी संरचना होनी चाहिए:

class Body {
  Point  position;
  double radius;
};

class Balls {
  vector<Body>  bodies;
  vector<Color>  color;

  void draw();
};

ऐसा करने का कारण यह है कि यदि एक साथ उपयोग किए गए डेटा को अलग-अलग सरणियों में रखा जाता है, तो एक जोखिम है कि वे कैश में एक ही स्लॉट के लिए प्रतिस्पर्धा करेंगे। इस प्रकार एक लोडिंग दूसरे को बाहर फेंक देगा।

तो ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग की तुलना में, आप जो कक्षाएं बनाते हैं, वे समस्या के आपके मानसिक मॉडल में संस्थाओं से संबंधित नहीं हैं। चूँकि डेटा उपयोग के आधार पर डेटा को एक साथ लम्प किया जाता है, इसलिए आपके पास डेटा ओरिएंटेड डिज़ाइन में अपनी कक्षाएं देने के लिए हमेशा समझदार नाम नहीं होंगे।

संबंधपरक डेटाबेस से संबंध

डेटा ओरिएंटेड डिज़ाइन के पीछे की सोच बहुत कुछ इसी तरह से है कि आप रिलेशनल डेटाबेस के बारे में कैसे सोचते हैं। रिलेशनल डेटाबेस को ऑप्टिमाइज़ करना भी कैश का अधिक कुशलता से उपयोग करना शामिल कर सकता है, हालाँकि इस स्थिति में, कैश CPU कैश नहीं है, बल्कि मेमोरी में पेज हैं। एक अच्छा डेटाबेस डिज़ाइनर भी संभवतः अलग-अलग तालिका में डेटा को अलग-अलग तालिका में विभाजित कर देगा, बड़ी संख्या में स्तंभों के साथ एक तालिका बनाने के बजाय केवल कुछ स्तंभ कभी उपयोग किए जाते हैं। वह कुछ तालिकाओं को अपभ्रंश करना चुन सकता है ताकि डिस्क पर कई स्थानों से डेटा तक पहुंच न हो। डेटा ओरिएंटेड डिज़ाइन के साथ की तरह ये विकल्प डेटा एक्सेस पैटर्न क्या हैं और प्रदर्शन अड़चन कहाँ है, को देखते हुए बनाया गया है।


4
इसके लिए धन्यवाद, आपने इसे बहुत अच्छी तरह से समझाया।
19

4
सही कहा; मुझे केवल एक प्रश्न मिला है। मान लें कि हमारे पास एक संरचना है struct balls {vector<vec3> pos; vector<vec3> velocity;}, प्रत्येक गेंद की स्थिति को अद्यतन नहीं कर रहा है क्योंकि आप वेग वेक्टर और स्थिति वेक्टर (हाँ आधुनिक मशीनों और कैश-लाइनों और सभी के बीच आगे पीछे, वास्तव में कैश को फेंकते हैं, यह है) यह भी सिर्फ एक उदाहरण)?
बाजीगर

14
ये हो सकता है। लेकिन याद रखें कि एक बार में पूरे पॉज़ सरणी को खींचा नहीं जाएगा। बस एक कैश लाइन, और संभव कुछ प्रीफ़ेटिंग। इसी तरह वेग के साथ। तो उनके लिए एक-दूसरे को पोज़ और वेक्टर के एक-दूसरे को रद्दी करना एक ही कैशेलाइन के लिए मैप करना होगा। यह निश्चित रूप से हो सकता है, यही वजह है कि सिफारिश एक चर में एक साथ उपयोग किए जाने वाले चर रखने के लिए है। इसलिए जैसे वेग और पोज़ एक वेक्टर में होंगे जबकि कलर दूसरे वेक्टर में होगा।
एरिक इंगोह

1
@roe आपको समूह गुण एक साथ होने चाहिए, जो एक साथ एक्सेस किए जाते हैं। गुणों के बीच कोई निर्भरता नहीं होनी चाहिए। इसलिए यह संरचना बेहतर होगी struct balls { vector<color> colors; vector<body> bodies; /* contains position and velocity */ }
danijar

2
@danijar I ने आपके सुझावों के साथ स्पष्टीकरण को अपडेट किया। मैं इसके बारे में बहुत कुछ कह सकता था, लेकिन यह वास्तव में एक लेख में बदल जाएगा।
एरिक इंगहेम

18

माइक एक्टन ने हाल ही में डेटा उन्मुख डिजाइन के बारे में एक सार्वजनिक बात की :

इसका मूल सारांश यह होगा: यदि आप प्रदर्शन चाहते हैं, तो डेटा प्रवाह के बारे में सोचें, उस संग्रहण परत को ढूंढें जो आपके साथ खराब होने की संभावना है और इसके लिए अनुकूलन करना मुश्किल है। माइक L2 कैश मिस पर ध्यान केंद्रित कर रहा है, क्योंकि वह रीयलटाइम कर रहा है, लेकिन मुझे लगता है कि यही बात डेटाबेस (डिस्क रीड) और यहां तक ​​कि वेब (HTTP अनुरोध) पर भी लागू होती है। यह सिस्टम प्रोग्रामिंग करने का एक उपयोगी तरीका है, मुझे लगता है।

ध्यान दें कि यह आपको एल्गोरिदम और समय की जटिलता के बारे में सोचने से अनुपस्थित नहीं करता है, यह सिर्फ आपका ध्यान सबसे महंगी ऑपरेशन प्रकार पर ध्यान केंद्रित करता है जिसे आपको अपने पागल सीएस कौशल के साथ लक्षित करना होगा।


14

मैं सिर्फ यह बताना चाहता हूं कि नोएल विशेष रूप से खेल विकास में हमारे सामने आने वाली कुछ विशिष्ट जरूरतों के बारे में बात कर रहा है। मुझे लगता है कि अन्य क्षेत्र जो वास्तविक समय नरम सिमुलेशन कर रहे हैं, उन्हें इससे फायदा होगा, लेकिन यह एक ऐसी तकनीक होने की संभावना नहीं है जो सामान्य व्यावसायिक अनुप्रयोगों में ध्यान देने योग्य सुधार दिखाएगी। यह सेट अप यह सुनिश्चित करने के लिए है कि प्रत्येक अंतिम बिट प्रदर्शन अंतर्निहित हार्डवेयर से बाहर निचोड़ा हुआ है।


माना। कुछ अन्य क्षेत्र जहां डेटा उन्मुख डिजाइन महत्वपूर्ण हैं: उच्च बैंडविड्थ उपकरणों (जैसे नेटवर्किंग या भंडारण) के लिए हार्डवेयर और फर्मवेयर; बड़े पैमाने पर वैज्ञानिक कंप्यूटिंग (जैसे मौसम सिमुलेशन, प्रोटीन तह), सिग्नल प्रोसेसिंग (जैसे ऑडियो, छवि, वीडियो), डेटा संपीड़न। ये "कम्प्यूटेशनल साइंस एंड इंजीनियरिंग" के अंतर्गत आते हैं, जिसे कभी-कभी अधिक विशिष्ट कंप्यूटर विज्ञान से एक अलग प्रमुख के रूप में पेश किया जाता है।
rwong

-3

डेटा ओरिएंटेड डिज़ाइन एक ऐसा डिज़ाइन है, जिसमें एप्लिकेशन के तर्क को प्रक्रियात्मक एल्गोरिदम के बजाय डेटा सेट से बनाया जाता है। उदाहरण के लिए

प्रक्रियात्मक दृष्टिकोण।

int animation; // this value is the animation index

if(animation == 0)
   PerformMoveForward();
else if(animation == 1)
  PerformMoveBack();
.... // etc

डेटा डिजाइन दृष्टिकोण

typedef struct
{
   int Index;
   void (*Perform)();
}AnimationIndice;

// build my animation dictionary
AnimationIndice AnimationIndices[] = 
  {
      { 0,PerformMoveForward }
      { 1,PerformMoveBack }
  }

// when its time to run, i use my dictionary to find my logic
int animation; // this value is the animation index
AnimationIndices[animation].Perform();

इस तरह से डेटा डिज़ाइन अनुप्रयोग के तर्क को बनाने के लिए डेटा के उपयोग को बढ़ावा देते हैं। विशेष रूप से वीडियो गेम में प्रबंधन करना आसान है, जिसमें एनीमेशन या किसी अन्य कारक के आधार पर हजारों तर्क पथ हो सकते हैं।


14
यह वास्तव में सही नहीं है। आप डेटा चालित डिज़ाइन के साथ डेटा उन्मुख डिज़ाइन को भ्रमित कर रहे हैं। मैंने यही किया जब तक मैं नोएल के लेख को नहीं पढ़ पाया और महसूस किया कि वह पूरी तरह से अलग चीज के बारे में बात कर रहा था।
एरिक इंगहेम

12
इसके अलावा, Indice एक शब्द नहीं है। "इंडेक्स" और "इंडेक्स" हैं और कुछ "इंडेक्स" भी हैं, लेकिन "इंडिस" कभी सही नहीं होता है।
बैक्सीसिमो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.