2016-09-28 11 views
6

पृष्ठभूमि

गेम इंजन विकास में हम आमतौर पर इष्टतम स्मृति और गणना प्रदर्शन के लिए डेटा उन्मुख डिजाइन का उपयोग करते हैं।मैं जंग में डेटा उन्मुख डिजाइन कैसे कार्यान्वित करूं?

चलिए एक उदाहरण के रूप में कण प्रणाली लेते हैं।

एक कण प्रणाली में, हम कणों की एक बहुत कुछ है, और प्रत्येक कण में इस तरह के पदों पर, वेग, आदि के रूप में कई गुण हो सकता है

सी ++ में एक ठेठ कार्यान्वयन इस तरह होगा:

struct Particle { 
    float positionX, positionY, positionZ; 
    float velocityX, velocityY, velocityZ; 
    float mass; 
    // ... 
}; 

struct ParticleSystem { 
    vector<Particle> particles; 
    // ... 
}; 

इस कार्यान्वयन की एक समस्या यह है कि कण गुण एक दूसरे के साथ interleaved हैं। यह मेमोरी लेआउट कैश अनुकूल नहीं है और सिम कंप्यूटेशंस के लिए उपयुक्त नहीं हो सकता है।

इसके बजाय एक डेटा उन्मुख डिजाइन में

, हम कोड निम्न लिखें:

struct ParticleAttribute { 
    size_t size; 
    size_t alignment; 
    const char* semantic; 
}; 

struct ParticleSystem { 
    ParticleSystem(
     size_t numParticles, 
     const ParticleAttribute* attributes, 
     size_t bufferSize) { 
     for (size_t i = 0; i < numAttributes; ++i) { 
      bufferSize += attributes[i].size * numParticles; 
      // Also add paddings to satisfy the alignment requirements. 
     } 
     particleBuffer = malloc(bufferSize); 
    } 

    uint8* getAttribute(const char* semantic) { 
     // Locate the semantic in attributes array. 
     // Compute the offset to the starting address of that attribute. 
    } 

    uint8* particleBuffer;  
}; 

अब हम केवल एक ही आवंटन किया है और प्रत्येक विशेषता लगातार स्मृति में रहता है। कणों अनुकरण के लिए, हम कोड निम्नलिखित लिख सकते हैं:

symplecticEuler(ps.getAttribute("positionX"), ps.getAttribute("velocityX"), dt); 

getAttribute समारोह किसी विशेष विशेषता के शुरू पता मिल जाएगा।

प्रश्न

मुझे पता है कि कैसे जंग में यह लागू करना चाहते हैं।

मेरा विचार पहले एक वर्ग है, जो कुल बफर आकार की गणना करने के लिए कई ParticleAttribute रों लेता ParticleSystem कहा जाता है बनाने के लिए है, तो बफर के लिए स्मृति को आबंटित। मुझे लगता है कि यह जंग सुरक्षित कोड में किया जा सकता है।

अगला चरण getAttribute फ़ंक्शन को लागू करना है, जो किसी विशेष विशेषता के प्रारंभिक पते का संदर्भ देगा। मुझे आपकी मदद की ज़रूरत है। मैं ऑफसेट के साथ कच्चा पता कैसे प्राप्त करूं और इसे वांछित प्रकार (जैसे फ्लोट *) पर डाल सकता हूं और उस कच्चे सूचक को जंग में एक परिवर्तनीय संदर्भ में लपेट सकता हूं?

इसके अलावा, मुझे लगता है कि मुझे उस कच्चे सूचक को सरणी के एक परिवर्तनीय संदर्भ में लपेटना चाहिए क्योंकि मुझे उस संदर्भ के माध्यम से चार तत्वों को लोड करने के लिए सिम lib का उपयोग करने की आवश्यकता है। मैं जंग का उपयोग करके इसे कैसे प्राप्त करूं?


अद्यतन: विशेषताओं के बारे में अधिक जानकारी प्रदान करें। गुणों की संख्या और विस्तृत जानकारी रनटाइम में निर्धारित की जाती है। गुणों के प्रकार भिन्न हो सकते हैं, लेकिन मुझे लगता है कि हमें केवल आदिम लोगों (f32, f64, ints, ...) का समर्थन करना होगा।

उत्तर

8

यह डीओडी लागू करने का एक बहुत ही जटिल तरीका है, और गेटर्स के लिए रन-टाइम लुकअप का उपयोग करने का विचार मुझे क्रिंग करता है।

struct Particles { 
    x: Vec<f32>, 
    y: Vec<f32>, 
} 

जो गुण पहले से जानते हुए भी आवश्यक है:

सरल संस्करण बस विशेषता प्रति एक स्मृति आवंटन है।

तब सभी ys प्राप्त करने के लिए कोई शेंगेन नहीं है, वे बस वहां बैठे हैं, पहले से टाइप किए गए हैं, आपके लिए प्रतीक्षा कर रहे हैं।

  • हम एक HashMap<String, xxx> उपयोग कर सकते हैं चलाने के समय पर देखने-अप करने के लिए किसी दिए गए विशेषता
  • हम एक enum उपयोग कर सकते हैं करने के लिए:


    विस्तार इस गतिशील रूप से निर्धारित करने के लिए विशेषताओं है कि जटिल नहीं है एक Value हैश-मैप में संग्रहीत किया जा सकता है जो विभिन्न रूपों (अन्य समाधान एक विशेषता का उपयोग करेगा)

यह हो जाता है:

#[derive(Debug, Hash, PartialEq, Eq)] 
enum Value { 
    UniformInt(i64), 
    UniformFloat32(f32), 
    UniformFloat64(f64), 
    DistinctInt(Vec<i64>), 
    DistinctFloat32(Vec<f32>), 
    DistinctFloat64(Vec<f64>), 
} 

struct Particles { 
    store: HashMap<String, Value>, 
} 

हम वैकल्पिक रूप से 6 हैश नक्शे इस्तेमाल कर सकते हैं ... लेकिन जब तक एक एक प्रायोरी जानता है कि किस प्रकार है (जब केवल लगता है कि एक एक स्ट्रिंग है), तो एक के माध्यम से देखने के लिए है सभी एक समय में एक हैशप: परेशान, और समय बर्बाद कर रहा है।

+0

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

+0

@TheBusyTypist: मैं देखता हूं ... कृपया प्रासंगिक विवरण के साथ प्रश्न संपादित करें। यह जानने के लायक भी होगा कि आपको केवल 'f32' का समर्थन करने की आवश्यकता है (इस मामले में एक हैश मैप <स्ट्रिंग, वीईसी <32>>' काफी अच्छा काम करेगा) या यदि आपको कई प्रकार का समर्थन करने की आवश्यकता है। –

+0

मुझे अन्य आदिम प्रकारों जैसे कि 'f64' या' int '(कण आईडी के लिए) का समर्थन करना है। जैसा कि आपने सुझाव दिया था, अब मुझे लगता है कि अलग-अलग 'हैश मैप' में समूहबद्ध विशेषताओं को उनके प्रकार से वैध समाधान हो सकता है। – TheBusyTypist

संबंधित मुद्दे