إدارة الذاكرة في Vulkan

من ويكي
اذهب إلى: تصفح، ابحث
هذه الصفحة لاتزال تحت الإنشاء، سيتم تحديثها مستقبلاً

إدارة الذاكرة أحد الأمور المهمة في Vulkan، هذا المقال سيعطيك صورة شاملة عن إدارة الذاكرة في Vulkan قبل الدخول في التفاصيل.

هناك نوعين من الذواكر في Vulkan: ذاكرة المضيف host memory وهي الذاكرة العشوائية المرتبطة بالمعالج، وذاكرة الجهاز device memory وهي الذاكرة التي يمكن للجهاز الوصول له، قد تكون منفصلة في كرت خارجي كما في حالة كروت الشاشة، وقد تكون نفس الذاكرة العشوائية كما هو الحال في معالجات الرسوميات المدمجة في بعض المعالجات وفي الجوالات، إذن فحتى ذاكرة المضيف لو كان يمكن للجهاز الوصول لها فهي أيضاً ذاكرة جهاز.

إدارة الذاكرة في Vulkan مسؤلية المبرمج بدلاً من المشغّل كونه أعلم بطريقة إدارة الذاكرة الأنسب لتطبيقه، فهو المسؤل عن تخصيص الذاكرة على الجهاز وإداراتها وتحريرها، فهناك حدود تفرضها Vulkan لعدد المرات التي يمكنك فيها مثلاً طلب حجز ذاكرة على الجهاز وذلك لأن عملية تخصيص الذاكرة مكلفة، انظر للعضو VkPhysicalDeviceLimits::maxMemoryAllocationCount، عندي مثلاً على GeForce GTX 980 Ti أقصى عدد هو 4096 وهذا نسبياً قليل، بمعنى أننا بحاجة لإستخدام أساليب تخصيص ذاكرة مثل أحواض الذاكرة memory pools بحيث نحجز ذاكرة كبيرة دفعة واحدة على الجهاز لتخزين مثلاً آلاف المصفوفات ثم ندير هذه الذاكرة يدوياً، حجز الذاكرة على الجهاز يتم باستخدام الدالة vkAllocateMemory() والتي تعطينا كائن VkDeviceMemory يمثل الذاكرة المحجوزة على الجهاز، يمكن نقل البيانات من وإلى الجهاز عن طريق استخدام vkMapMemory() والتي تخصص جزء من ذاكرة المضيف بحيث يمكن الكتابة والقراءة من العنوان المخصص للإدخال والإخراج من وإلى الجهاز.

تلك الذاكرة المحجوز مجرد بيانات خام لامعنى لها، لذا لإعطائها معنى يصف محتوياتها مثل نوع البيانات والحجم نستخدم كائنات الموارد resources، هناك نوعين من الموارد في Vulkan: النوع الأول هو الذاكرة الوسيطة buffers ممثلة في الكائن VkBuffer حيث تسمح لك بتخزين أي نوع من البيانات بأي تنسيق مثل المتغيرات، والثوابت، والمصفوفات، وحتى الصور، والنوع الثاني من الموارد هي الصور images ممثلة بالكائن VkImage والذي يمكن إنشاءه باستخدام الدالة vkCreateImage() وهي نوع خاص من الذاكرة الوسيطة لها تنسيق (مثلاً 8 بت لكل مركب لوني RGBA) وأبعاد (أحادية، ثنائية، ثلاثية البعد)، وقد تكون الصور مضغوطة، ويمكن القراءة منها والكتابة إليها بطرق مختلفة.

للموارد شروط تحدد حجم الذاكرة ومحاذاة عناوين الذاكرة، لذا قبل تخصيص الذاكرة يجب إستدعاء vkGetBufferMemoryRequirements() للذاكرة الوسيطة أو vkGetImageMemoryRequirements() للصور.

الموارد تحدد فقط معلومات ذاكرة وسيطة أو صورة غير محددة وليست مرتبطة بالذاكرة المحجوز على الجهاز بعد، لذا للربط بين الذاكرة المحجوزة والمورد نستخدم vkBindBufferMemory() للذاكرة الوسيطة أو vkBindImageMemory() للصور، لو استخدمنا فكرة أحواض الذاكرة، فهنا يمكننا تحديد مكان هذا المورد في الحوض، ومعلومات الحجم في المورد تحدد النهاية.