2017-09-26 10 views
9

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

के रूप में मैं समझता हूँ कि यह स्मृति गठबंधन बस एक specefic वेतन वृद्धि कुछ बाइट राशि है कि डिवाइस वास्तव में पसंद करती है की एक बहु है कि कम से शुरू होता है। मेरा भ्रम कोड

// The 256 byte aligned size of our uniform structure 
let alignedUniformsSize = (MemoryLayout<Uniforms>.size & ~0xFF) + 0x100 

वे वर्दी संरचना के आकार और बाइट को खोजने के लिए इसका उपयोग करते हैं। मैं इस बारे में उलझन में हूं कि यहां बाइनरी ऑपरेशंस क्यों हैं, मुझे सच में यकीन नहीं है कि वे क्या करते हैं।

यदि यह इस संरेखित आकार को इस तरह बफर बनाने के लिए उपयोग किया जाता है। मैं काफी यकीन है कि बफर आवंटित करता है कि बाइट स्वचालित रूप से गठबंधन स्मृति और आगे से वर्दी के लिए स्मृति भंडारण स्थान के रूप में प्रयोग किया जाता है कर रहा हूँ।

let buffer = self.device.makeBuffer(length:alignedUniformsSize * 3, options:[MTLResourceOptions.storageModeShared]) 

इसलिए अनिवार्य रूप से बाइट गठबंधन स्मृति आवंटित करने की परेशानी से गुजरने के बजाय वे धातु को उनके लिए करते हैं।

क्या कोई कारण है कि उन्होंने let allignedUniformsSize = पर उपयोग की जाने वाली रणनीति Int या Float आदि जैसे अन्य प्रकारों के लिए काम नहीं करेगी?

उत्तर

12

आइए बात करते हैं पहले के बारे में तुम क्यों गठबंधन बफ़र्स चाहते हैं, तो हम बिटवाइज़ गणित के बारे में बात कर सकते हैं।

हमारा लक्ष्य एक धातु बफर आवंटित करना है जो हमारी वर्दी की तीन (ट्रिपल-बफर्ड) प्रतियों को स्टोर कर सकता है (ताकि हम बफर के एक हिस्से को लिख सकें जबकि GPU दूसरे से पढ़ता है)। इन तीन प्रतियों में से प्रत्येक से पढ़ने के लिए, हम एक ऑफसेट जब currentBufferIndex * uniformsSize तरह बफर कुछ बंधन, आपूर्ति। कुछ धातु उपकरणों को इन ऑफसेट को 256 के गुणक होने की आवश्यकता होती है, इसलिए हमें इसके ऑफसेट के रूप में currentBufferIndex * alignedUniformsSize जैसे कुछ उपयोग करने की आवश्यकता है।

हम कैसे एक पूर्णांक 256 की अगली उच्चतम कई करने के लिए "को ख़त्म कर" करते हैं? हम इसे "unaligned" आकार के सबसे कम 8 बिट्स को प्रभावी ढंग से गोल करने के बाद कर सकते हैं, फिर 256 जोड़कर, जो हमें अगले उच्चतम एकाधिक प्राप्त करता है। गोलाकार नीचे भाग 255 के 1 पूरक (~) के साथ बिटवाई एंडिंग द्वारा हासिल किया जाता है, जो (32-बिट में) 0xFFFFFF00 है। गोलाकार अप 0x100 जोड़कर किया जाता है, जो 256 है।

दिलचस्प बात यह है कि यदि बेस आकार पहले से ही गठबंधन हो गया है, तो यह तकनीक किसी भी तरह से घूमती है (उदाहरण के लिए, 256 से 512 तक)। एक पूर्णांक विभाजन की लागत के लिए, आप इस अपशिष्ट से बच सकते हैं:

let alignedUniformsSize = ((MemoryLayout<Uniforms>.size + 255)/256) * 256 
+0

इस लाइन के लिए बहुत बहुत धन्यवाद, सामान्य अंकगणितीय संस्करण इतना अधिक पठनीय है! – zsero

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