السلام عليكم ورحمة الله وبركاته،
في العقد الأخير من الزمن أصبحت معالجات الرسوميات (GPUs) مقيماً دائماً في أجهزة الحاسوب ومنصات الألعاب المختلفة. هذا المعالج هو معالج آخر يختلف عن المعالج المركزي (CPU) في العديد من النواحي. كما أن معالج الرسوميات يعمل باستقلال شبه تام عن المعالج المركزي، فهما فقط يتواصلا مع بعضهما بين الفينة والأخرى عن طريق ذاكرة مشتركة. الهدف من هذا التصميم هو تخفيف العبء عن المعالج المركزي، ونقل حسابات الرسوميات لتتم على معالج الرسوميات على التوازي مع المعالج المركزي.
في هذه التدوينة سنتعرف على العلاقة بين هذين المعالجين، وكيفية تحقيق التوازي في العمل بينهما من خلال بعض الشروحات.
أسـْـوَد وأزرق
يختلف معالج الرسوميات عن المعالج المركزي في صفات كثيرة. منها:
- مجموعة التعليمات التي يدعمها معالج الرسوميات محدودة للغاية مقارنة بتلك التي يدعمها المعالج المركزي.
- مجموعة تعليمات معالج الرسوميات تركز على حزم بيانات رباعية أو من مضاعفات ذلك، بينما تعليمات المعالج المركزي أكثر عموماً من ذلك.
- عدد التعليمات المسموح تنفيذها في البرنامج الواحد محدود في معالج الرسوميات، ومفتوح في المعالج المركزي.
- معالج الرسوميات عديد الأنوية (many-core)، يبدأ من 16 وصولاً إلى المئات. المعالجات المركزية الحالية متعددة الأنوية (multi-core) تصل لثمان أنوية كحد أقصى.
هذان المعالجان يعيشان على لوحة أم واحدة، ويحتاجان للتواصل إن أردنا إنجاز أي شيء مثير للاهتمام على معالج الرسوميات. من المقارنة السابقة، نجد أن المعالج المركزي أقدر وأكثر عموماً. لذلك هو قادر على الاحتفاظ برتبته كمعالج مركزي. هذا يعني أنه هو الآمر الناهي وله القدرة على تسيير بقية الأجهزة في الحاسوب، متضمنة معالج الرسوميات. إذن يبقى لدينا السؤال: كيف يقوم المعالج المركزي بإعطاء الأوامر لمعالج الرسوميات؟ فلننظر إلى الشكل 1 أدناه:
شكل 1. التواصل بين المعالج المركزي ومعالج الرسوميات
هذه النظرة المبسطة تظهر لنا كيفية التواصل بين المعالجَين. المعالج المركزي يقوم بتنفيذ البرنامج أو اللعبة والذي يقوم بدوره باستخدام واجهة برمجة رسوميات مثل دايركت ثري دي أو أوبن جي إل. هذه الواجهات تولد أوامر رسم توضع في طابور. يقوم معالج الرسوميات بمراقبة هذا الطابور باستمرار لسحب الأوامر منه أولاً بأول وتنفيذها. قد يقوم المعالج المركزي بإضافة المزيد من الأوامر إلى الطابور بينما يقوم معالج الرسوميات بتنفيذ أمر ما. بعد إضافة الأمر إلى الطابور، لا يحتاج المعالج المركزي للانتظار ريثما يتم تنفيذ الأمر، وإنما يستمر في تنفيذ البقية من البرنامج. هذا هو أهم وجه من أوجه التوازي بين معالج الرسوميات والمعالج المركزي.
أمرُك سيدي
فلنلقِ نظرة على بعض أنواع الأوامر التي نرسلها أثناء رسمنا للمشاهد في البرنامج أو اللعبة:
- تعديل إحداثيات وإعدادات ضوء.
- تفعيل دمج ألفا.
- تغيير وجهة الرسم (الرسم على الشاشة، أو على سطح جانبي).
- اختيار مظلل آخر.
- تغيير قيمة بعض الثوابت في المظلل الحالي.
- نسخ محتوى سطح رسم إلى سطح رسم آخر.
- رسم مثلثات باستخدام الحالة القائمة.
- … المزيد والمزيد …
يختلف الزمن اللازم لتنفيذ الأوامر من معالج رسوميات لآخر. لكن أبرز الأوامر وأهمها هو ذلك الخاص برسم المثلثات (طبعاً). تنفيذ هذا الأمر يستغرق زمناً مختلفاً وفقاً للعديد والعديد من العوامل. مثلاً:
- عدد المثلثات. كلما كثرت، طال زمن تنفيذ الأمر.
- مساحة الشاشة التي تغطيها هذه المثلثات. فلو ملأت كامل الشاشة لاستغرقت زمناً أكثر لرسمها.
- تعقيد المظلل المستخدم في الرسم. كلما ازداد تعقيداً ازداد زمن تنفيذ أمر الرسم.
- نوع وهيئة سطح الرسم المستهدف. كلما ازداد عرض البكسل في الذاكرة بطؤ الأداء.
- نوع وهيئة البيانات المستخدمة في المظلل من إكساءات وثوابت وقيم رؤوس.
- وضعية اختبار العمق (depth test state). توجد بضعة تفاصيل هنا سنتحدث عنها لاحقاً.
- وضعية دمج ألفا. في الحالة العامة تفعيل دمج ألفا يبطئ الأداء. جهازي نينتيندو وي (Wii) وجيم كيوب (GameCube) هما من الاستثناءات التي لا يتأثر أداؤها بوضعية دمج ألفا.
للحصول على أفضل أداء في التوازي بين المعالج المركزي ومعالج الرسوميات، يجب أن نرسل أوامر قليلة لكنها تستغرق وقتاً على معالج الرسوميات. في هذا الوقت يعمل المعالج المركزي على حسابات أخرى. لو كانت الأوامر تستغرق وقتاً قليلاً فما سيحدث هو أن معالج ا��رسوميات سينتهي من عمله ثم يدخل في حالة انتظار وتأمل حتى وصول المزيد من الأوامر. هذا تبذير ونقصان فاعلية. في هذه الحالة يجب الاستفادة من الزمن الفائض في حسابات إضافية تحسن جودة الصورة مثلاً.
بالمقابل، لو أن المعالج المركزي ملأ الطابور بكمية كبيرة من الأوامر التي تستغرق وقتاً طويلاً للتنفيذ على معالج الرسوميات، فإن المعالج المركزي سيصل إلى لحظة يتعطل عندها انتظاراً ريثما يفرغ الطابور قليلاً لتكديس المزيد الأوامر. وهذا أيضاً تبذير ونقصان فاعلية في الأداء، حيث أننا لا نريد لمعالجاتنا أن تنتظر وتتأمل دون عمل.
وهكذا نرى أن من المهام الهامة لمبرمج الرسوميات هي مهمة متابعة الأداء لكلا المعالجين والتأكد من عدم وجود حالات الانتظار هذه أو على الأقل التأكد من اقتصارها على فترات محدودة ضمن حد مقبول. هذا يحتاج لبعض الأدوات التي يجب على مبرمج محرك الرسوميات أن يكتبها بنفسه. سنتحدث عنها في عدد قادم من هذه السلسلة بإذن الله…
السلام عليكم ورحمة الله وبركاته.