بسم الله الرحمن الرحيم السلام عليكم جميعا اليوم أبغى أفتح نقاش معكم حول علاقة بيئة الدوت نت ببرمجة الالعاب وهل يفضلها أي منكم أعتقد ان الجميع متفق انه لعمل العاب ذات كفائة عالية جدا أي لجعل هذه الالعاب تكون في ال real-time لابد من استخدام لغة سريعة جدا تقارب في سرعتها لغة الـ assembly وذلك طبعا مع وجود المترجمات الحديثة التى تقدم نوعا من أنواع الـ optimization علي الكود بحيث تنتج binary or native code سريع جدا عند تنفيذه
ولاننا نعمل ان بيئة الدوت نت ما هي الا مجموعة من الـ Classes والتى تحتاج عند تنفيذ كودها في اغلب الاحيان الي ملفات runtime خاصة بها يطلق عليها .Net framework runtime والتى وصلت حاليا الى الاصدار 3.5 منها
ولكنى قد قرأت سابقا أنه يمكن عمل برنامج باحدى لغات الدوت نت وجعله يعمل دون الحاجة الى ملفات الـ runtimeوذلك باستخدام احد الادوات التي تقوم بسحب المكتبات التى يحتاجها برنامجك من مكتبة ال runtime ووضعها داخل المجلد الذي يحتوي علي برنامجك.
وأنا أعتقد ان بيئة الدوت نت وأعنى بذلك اللغات التي تعمل فقط علي الـ .net frameworkمصممة فى الاساس لعمل تطبيقات الويب والتطبيقات التجارية وكذلك لعمل التطبيقات الصغيرة – أما التطبيقات التى تحتاج لسرعة عالية في التنفيذ مثل تطبيقات المحاكاة والالعاب فأعتقد أنها تصمم باللغات التي تقدم سرعة عالية جدا مثل c++/cli
هذا ما اعتقده من وجهة نظري عن علاقة الدوت نت ببرمجة الالعاب ولكنى اعلم ان شركة ميكروسوفت اصدرت من زمان بيئة تطوير الالعاب بالاعتماد علي لغة c# وتسمي XNA وحاليا ظهر منها الاصدار الثانى وهي تقدم بيئة شبه متكاملة لتطوير الالعاب لتعمل علي انظمة windows وكذلك علي XBOX
نرجو من الاخوة الزملاء ان يطرحوا رأيهم حول الموضوع والسلام عليكم ورحة الله
الأداء وإدارة الذاكرة: الكلمتان الأبديتان التي تسمعها من كل مبرمج ألعاب متعصب للغة ++C.. سأتكلم من وجهة نظري الشخصية وخبرتي في التعامل مع دوت نيت.
بالرغم مما عُـرف عن الألعاب أنها تحتاج إلى كامل إمكانيات الجهاز، إلا أن الواقع أن هذه الإمكانيات (والتي تتيحها لنا ++C) لا يتم استثمارها كما يجب إلا فيما ندر عند من رحم ربك من المبرمجين.
خذ عندك كمثال محرك أنريل Unreal. يقوم محرك أنريل ببساطة بإدارة الذاكرة عن طريق استخدام garbage collector يشابه الـ garbage collector الذي تجده في دوت نيت، مع فرق وحيد، وهو أنه فاشل جداً بالمقارنة... ونحن هنا نتكلم عن محرك يتم استخدامه في ألعاب حديثة جداً وكبيرة (مثل Unreal Tournament و Gears of War) ويستمتع بها الملايين كل يوم. عندما أرى هذا أسأل نفسي... لم عذبوا أنفسهم لبناء هذا الـ garbage collector بدلاً من اعتماد الـ gc في دوت نيت مثلاً؟ أؤكد لك أن هاتين اللعبتين على الأقل يمكن إعادة بناؤهما بدوت نيت وبرأيي لو أحسن المبرمجون العمل فإنهم سيستطيعون الحصول أيضاً على أداء أسرع!
ثم تأتي لديك لغة C++/CLI والتي تتيح لك الدمج بين قدرات ++C اللا متناهية مع بساطة وفعالية مكتبات دوت نيت، كل هذا تحت أداء فائق يقترب من أداء مترجم ++C المجرد. وهنا أيضاً يطرح السؤال نفسه. لم يتم تجاهل مثل هذه الإمكانيات الرائعة وإعادة بناء الدولاب؟
خبرتي الشخصية مع دوت نيت في عالم الرسوميات كانت من خلال المنتج DSK|Planet والذي يقوم بتمثيل الكواكب بمبدأ مشابه لجوجل إيرث:
وقد كان أداء الوحدة ممتاز جداً وهي مكتوبة بـ C++/CLI ويتم التعامل معها من أي لغة دوت نيت أخرى على رأسها #C...
أنا طبعاً لا أعمم هنا، فهناك ألعاب بالفعل تحتاج إلى إدارة ذاكرة خاصة وحسابات سريعة جداً، كما هي الحال في ألعاب الاستراتيجي الفورية. حيث أن هناك أعداد كبيرة من الوحدات التي تموت ومن ثم تعيش ومن ثم تموت وهكذا. هذه الألعاب لا تستطيع العمل باستخدام garbage collector عام كالذي نجده في دوت نيت.
ما أود أن أقوله هو أن مشكلة الأداء وإدارة الذاكرة هي في كثير من الأحيان تنبع عن سوء تفكير أو تخطيط من المبرمج. لذا فالحل هو المران والمران والتعلم من الأخطاء. أؤمن بشدة أن المحترف في دوت نيت يستطيع أن ينتج ألعاباً كبيرة وغاية في الإمتاع، وأؤمن بشدة أن ليس كل لعبة مكتوبة بالـ ++C تستفيد من إمكانيات هذه اللغة بالشكل الأمثل...
هذه وجهة نظري وقد أكون على خطأ (كما هي الحال في أغلب الأحيان).. لا أعلم ماذا يعتقد بقية الأصدقاء، وأود أن أسمع آراءهم...
لكن انت اشرت فى كلامك انه اذا كانت اللعبة التى نريد عملها مثل معظم الالعاب التى يمكن ادارتها بالدوت نت والاستفادة من الامكانيات الرائعة التى تقدمها بحق بيئة الدوت نت ولكن كما تعلم ان معظم المكتبتات SDK كتبت في الاساس للعمل على لغة ال C++ يعنى انت ترى ميكروسوفت على حد علمى اوقفت دعم مكتبة الدايركت اكس على الدوت نت وكذلك معظم المكتبات او محركات الالعاب او محركات الرسوميات مثل irrlicht فانه يقدم كل التحديثات الجديدة في محرك مكتبة ال C++ بينما مكتبة الدوت نت من هذا المحرك مع انها منظمة جدا وسهلة الاستخدام الا انها لا يتم تحديثها بسرعة تحديث المكتبات التى لا تعتمد على اطار عمل الدوت نت واعتقد ان هذا يرجع ان معظم المبرمجين كما اشرت يفضلون او قل يعتقدون ان اطار عمل الدوت نت لا يصلح لعمل الالعاب والتى تحتاج لحسابات سريعة وكثيرة جدا
ولكنى مقتنع بوجهة نظرك انه يمكن الاستفادة من امكانيات بيئة الدوت نت واولها ادارة الذاكرة اليا وكذلك الاستفادة من ال classic c++ language وكل هذا متاح داخل ال C++/CLI بل توفر ايضا هذه اللغة كافة مكتبات السى بلس بلس التقليدية بجانب مفهوم يناظر المؤشرات داخل ذاكرة البيئة المدارة MANAGED وهذا المفهوم يسمى handle حيث يمكن ان تعرف متغير من نوع handle ليشير الى متغير اخر داخل ذاكرة ال GC المدارة وبالتالى فان المبرمج حتى لو نسى ان يحرر ذاكرة هذا الكتغير فان اطار عمل الدوت نت سوف يقوم بعمل اللازم
مثال على استخدام ال handle int^ x; هنا عرفنا متغير مؤشر فى ذاكرة ال GC يمكن استخدامه مثل المؤشر العادى فى ال C++ Classic
وفي النهاية كنت قد قرأت في موقع ما انها تم اختبار بيئة الدوت نت ببرمجة لعبة كبيرة عليها وكان الفارق فى الاداء غير ملحوظ
لكنى كنت اريد وجهة نظرك في الاتى ماذا لو كنت اريد ان استدعى دالة لتؤدى وظيفة ما وهذه الوظيفة موجودة فى اطار الدوت نت وقد يكون استخدامها اسهل من استدعاء نظيرتها الموجودة في ال NATIVE API فأى الدالتين استدعى ولماذا؟
وفي 14 مارس 2008 04:24 ص، أعرب ahmed ezz عن رأيه بالموقف كالآتي:
ولكن كما تعلم ان معظم المكتبتات SDK كتبت في الاساس للعمل على لغة ال C++ يعنى انت ترى ميكروسوفت على حد علمى اوقفت دعم مكتبة الدايركت اكس على الدوت نت وكذلك معظم المكتبات او محركات الالعاب او محركات الرسوميات مثل irrlicht فانه يقدم كل التحديثات الجديدة في محرك مكتبة ال C++ بينما مكتبة الدوت نت من هذا المحرك مع انها منظمة جدا وسهلة الاستخدام الا انها لا يتم تحديثها بسرعة تحديث المكتبات التى لا تعتمد على اطار عمل الدوت نت واعتقد ان هذا يرجع ان معظم المبرمجين كما اشرت يفضلون او قل يعتقدون ان اطار عمل الدوت نت لا يصلح لعمل الالعاب والتى تحتاج لحسابات سريعة وكثيرة جدا
أولاً باستخدام C++/CLI فأنت تكتب برنامج ++C نظامي اعتيادي يستطيع التعامل مع كل الـ APIs والـ SDKs السابقة، بالإضافة إلى إمكانية التعامل مع الـ CLR في دوت نيت بطريقة راقية جداً وواضحة. لدرجة أن هجاء syntax البرامج بـ C++/CLI يتفوق بالسهولة على #C، وقد قامت #C مؤخراً باستعارة بعض التراكيب من C++/CLI لتبسيط #C. كما هي عادة ++C فإن C++/CLI تعتبر هي لغة دوت نيت الأسرع والأقوى وتسمح لك بفعل أشياء مع الـ CLR لا تسمح بها اللغات الأخرى. هذا رأيي وهو تعليق رسمي من مايكروسوفت أيضاً، يمكنك قراءته هنا:
أما بالنسبة لموضوع Managed DirectX أو حتى أي طبقة Managed من أي محرك حديث، فإنني أعتقد أن المهمة الآن أصبحت أسهل بكثير، وفي أغلب الأحيان لا داعي لها أساساً. فأنا الآن أستطيع بناء لعبة دوت نيت باستخدام DirectX الأساسي دون الحاجة لـ Managed DirectX، وكذلك هو الحال بالنسبة لاستخدام محركات الـ ++C الحالية. الكود المكتوب هو كود دوت نيت، وهو قادر على استدعاء إجراءات والتعامل مع المتغيرات من الـ ++C البحتة بشفافية تامة وكأنك تستخدم بيئة واحدة. لذا لا أرى داعي الآن أساساً لوجود طبقة Managed من DirectX أو محرك ألعاب. (إلا أن هناك حالات خاصة لا يمكن التهرب منها، وعندها أيضاً العملية أسهل بـ C++/CLI).
في 14 مارس 2008 04:24 ص، قال ahmed ezz بهدوء وتؤدة:
لكنى كنت اريد وجهة نظرك في الاتى ماذا لو كنت اريد ان استدعى دالة لتؤدى وظيفة ما وهذه الوظيفة موجودة فى اطار الدوت نت وقد يكون استخدامها اسهل من استدعاء نظيرتها الموجودة في ال NATIVE API فأى الدالتين استدعى ولماذا؟
حسناً يمكنك انتقاء أي الدالتين. الخيار الأمثل هو الخيار الذي يحقق لك أداء أسرع في هذه الحالة. أثناء عمل برنامج الـ C++/CLI أنت تنفذ تعليمات أسيمبلي ناتجة من مترجم ++C البحتة، مع تعليمات ناتجة من CLI. هناك ضريبة أداء يتم دفعها عند التحويل من تعليمات ++C إلى تعليمات CLI، وهذه الضريبة ليست ذات قيمة في أغلب الحالات، إلا أنه في بعض الحالات الأخرى فإن الكلفة قد تكون كبيرة جداً. لقد قمت بكتابة مقالة كاملة عن هذا الموضوع في كتاب ShaderX6، وسأقتبس هنا الجزء الذي له علاقة بسؤالك:
Minimize context switches The switch between native and managed contexts costs around 50 to 300 cycles. This can be a problem if it happens in a very frequent fashion. It is best to avoid tight loops that call functions from the other context. For example, consider a list of world positions that we need to use to render some instances. The list is stored in a managed container, and our rendering function is a pure native one. The following code will involve a lot of context switches and would have suboptimal performance: List ^instancePositions = world->GetTreeInstances();for each (Vector3 pos in instancePositions) pRenderer->DrawInstance(pGeometry,pos.x,pos.y,pos.z); An alternative solution would be to convert the data to a native array and iterate on that instead. The conversion happens only when changes occur in the managed array, so the conversion does not have to be done each frame. On the other hand, if the number of iterations in the loop is not going to be high enough, then the performance loss might not be even noticeable. The online article [TOUB04] describes this topic in detail.
من هذه المناقشة تعملت انه لابد ان اجلا أو عاجلا المفترض ان يكون لدى على الاقل خلفية عن امكانيات بيئة ال C++/CLI فهل يمكنك أن تقترح اسم كتاب او موقع يكون جيد لمعرفة امكانيات اللغة C++/CLI بالتحسينات الجديدة التى فيها ويفضل ان يكون كتاب يعرض مقارنة بين الميزة الموجودة في ال C++/CLI ويقارن نظيرتها ان وجدت في ال NATIVE C++
انا من حوالى سنتيت كنت قد قرأت في كتاب Begining Visual c++ 2005 وهو كان يتحدث عن ال C++/CLI مع التطرق للغة الاصلية Native لكنى لم اعره اهتماما كبيرا وأتمنى ان تدلنا على اسم مرجع أو كتاب تنصح به لمن يريد أن يتعرض لمثل تلك الامكانيات الجديدة وخصوصا يفضل ان يكون له علاقة ببرمجة الالعاب اي يفضل ان يكون اخذا في اعتباره هذا النوع من برمجة التطبيقات