تحسين عرض مشهد من كارتون ديزني "Moana". الجزء الأول

قدمت Walt Disney Animation Studios (WDAS) مؤخرًا هدية لا تقدر بثمن لمجتمع البحث عن طريق إطلاق مشهد جزيرة كامل من الرسوم المتحركة Moana . تشغل الأشكال الهندسية والأنسجة لإطار واحد أكثر من 70 غيغابايت من مساحة القرص. هذا مثال رائع على درجة التعقيد التي يجب أن تتعامل معها أنظمة التقديم اليوم ؛ لم يسبق أن كان الباحثون والمطورون المشاركون في العرض خارج استوديوهات الأفلام قادرين على العمل مع مثل هذه المشاهد الواقعية.

إليك ما تبدو عليه نتيجة عرض مشهد باستخدام pbrt الحديث:


جزيرة من موانا تم تقديمها بواسطة pbrt-v3 بدقة 2048x858 مع 256 عينة لكل بكسل. كان إجمالي وقت العرض على مثيل 12-core / 24-thread من Google Compute Engine بتردد 2 غيغاهرتز مع أحدث إصدار من pbrt-v3 ساعة واحدة و 44 دقيقة و 45 ثانية.

من جانب ديزني ، كانت مهمة ضخمة ، كان عليها استخراج المشهد من تنسيقه الداخلي وتحويله إلى الشكل المعتاد. شكر خاص لها على الوقت المستغرق في التعبئة والتغليف وإعداد هذه البيانات للاستخدام على نطاق واسع. أنا متأكد من أن عملهم سوف يكافأ بشكل جيد في المستقبل لأن الباحثين يستخدمون هذا المشهد لدراسة مشاكل عرض المشاهد بكفاءة لهذا المستوى من التعقيد.

لقد علمني هذا المشهد كثيرًا بالفعل وسمح لي بتحسين جهاز عرض pbrt ، ولكن قبل الدخول في هذا ، سأخبر قصة قصيرة لفهم السياق.

التجزئة التي لم تكن كذلك


منذ سنوات عديدة ، أثناء إجراء تدريب داخلي في فريق عرض Pixar ، تعلمت درسًا غريبًا: تظهر الأشياء "المثيرة" دائمًا عند تمرير بيانات الإدخال إلى نظام البرنامج والتي تختلف بشكل كبير عن كل ما كان من قبل. حتى في أنظمة البرامج المكتوبة جيدًا والناضجة ، تؤدي الأنواع الجديدة من المدخلات دائمًا إلى اكتشاف عيوب غير معروفة في التنفيذ الحالي.

لقد تعلمت هذا الدرس لأول مرة أثناء إنتاج لعبة Toy Story 2 . في أحد الأيام ، لاحظ شخص ما أنه تم قضاء قدر مذهل من الوقت في تحليل ملفات وصف مشهد RIB. قام شخص آخر من فريق التقديم (أعتقد أنه كان Craig Kolb) بإطلاق المحلل وبدأ في اكتشافه.

اتضح أن معظم وقت التحليل كان مشغولًا بعمليات البحث في جدول التجزئة المستخدم في تدريب السلسلة . كان جدول التجزئة صغيرًا إلى حد ما ، ربما 256 عنصرًا ، وعندما تم تجزئة عدة قيم في خلية واحدة ، نظم سلسلة. بعد التنفيذ الأول لجدول التجزئة ، مر الكثير من الوقت وكان هناك الآن عشرات الآلاف من الكائنات في المشاهد ، لذلك سرعان ما تم ملء هذه الطاولة الصغيرة وأصبحت غير فعالة.

كان من المستحسن ببساطة زيادة حجم الجدول - كل هذا حدث في ذروة سير العمل ، لذلك لم يكن هناك وقت لنوع من الحل الأنيق ، على سبيل المثال ، توسيع حجم الطاولة عند ملئه. نجري تغييرًا في سطر واحد ، ونعيد بناء التطبيق ، ونجري اختبارًا سريعًا قبل الالتزام و ... لا تحدث تحسينات في السرعة. يستغرق البحث في جدول التجزئة نفس الوقت. رائع!

بعد مزيد من الدراسة ، وجدنا أن وظيفة جدول التجزئة المستخدمة كانت مشابهة لما يلي:

int hash(const char *str) { return str[0]; } 

(سامحني يا بيكسار ، إذا كشفت عن رمز مصدر RenderMan السري للغاية).

تم تطبيق وظيفة "التجزئة" في الثمانينيات. في ذلك الوقت ، ربما اعتبر المبرمج أن التكلفة الحسابية للتحقق من تأثير جميع الأحرف في السلسلة على قيمة التجزئة ستكون عالية جدًا ولا تستحق ذلك. (أعتقد أنه إذا كان هناك عدد قليل من الأشياء و 256 عنصرًا في جدول التجزئة في المشهد ، فهذا يكفي.)

ساهم تنفيذ قديم آخر: منذ اللحظة التي بدأت فيها Pixar في إنشاء أفلامها ، نمت أسماء الأشياء في المشاهد كثيرًا ، على سبيل المثال ، "BuzzLightyear / LeftArm / Hand / IndexFinger / Knuckle2". ومع ذلك ، استخدمت بعض المراحل الأولية من خط الأنابيب مخزنًا مؤقتًا بطول ثابت لتخزين أسماء الأشياء وتقصير جميع الأسماء الطويلة ، مع الحفاظ على النهاية فقط ، ومع الحظ ، أضاف علامة حذف في البداية ، مما يوضح أن جزءًا من الاسم فقد: "... year / LeftArm / Hand / IndexFinger / Knuckle2 ".

بعد ذلك ، كانت جميع أسماء الكائنات التي شاهدها العارض بهذا الشكل ، وقد قامت دالة التجزئة بتجميعها كلها في جزء واحد من الذاكرة كـ "." ، وكان جدول التجزئة في الواقع قائمة كبيرة مرتبطة. الأيام الخوالي. على الأقل ، بعد أن اكتشفنا ذلك ، أصلحنا هذا الخطأ بسرعة.

ابتكار مثير للاهتمام


تم تذكر هذا الدرس في العام الماضي عندما اتصلت بي هيذر بريتشيت و راسموس تامستورف من WDAS وسألتني إذا كنت مهتمًا بالتحقق من الجودة المحتملة لعرض المشهد من Moana في pbrt 1 . بطبيعة الحال ، وافقت. كنت سعيدًا للمساعدة وكنت أتساءل كيف ستسير الأمور.

كان المتفائل الساذج بداخلي يأمل ألا تكون هناك مفاجآت كبيرة - في النهاية ، تم إصدار النسخة الأولى من pbrt منذ حوالي 15 عامًا ، واستخدم العديد من الأشخاص ودرسوا رمزها لسنوات عديدة. يمكنك التأكد من أنه لن يكون هناك أي تدخل مثل وظيفة التجزئة القديمة من RenderMan ، أليس كذلك؟

بالطبع ، كان الجواب لا. (ولهذا السبب أكتب هذا وبعض المنشورات الأخرى.) على الرغم من خيبة أملي قليلا لأن pbrt لم يكن "خارج الصندوق" ، ولكن أعتقد أن تجربتي مع مشهد Moana كانت التأكيد الأول على قيمة نشر هذا المشهد ؛ أصبح pbrt بالفعل نظامًا أفضل نظرًا لأنني اكتشفت كيفية التعامل مع هذا المشهد.

الاداءات الأولى


بعد الوصول إلى المشهد ، قمت بتنزيله على الفور (استغرق الأمر عدة ساعات مع اتصال الإنترنت المنزلي الخاص بي) وتفريغه من القطران ، وتلقي 29 جيجابايت من ملفات pbrt و 38 جيجابايت من خرائط نسيج ptex 2 . حاولت بكل ثبات عرض المشهد على نظام منزلي (مع ذاكرة وصول عشوائي سعتها 16 غيغابايت ووحدة معالجة مركزية رباعية النواة). بعد العودة إلى جهاز الكمبيوتر بعد مرور بعض الوقت ، رأيت أنه تم تجميده ، وكانت ذاكرة الوصول العشوائي ممتلئة ، وكان pbrt لا يزال يحاول إكمال تحليل وصف المشهد. سعى نظام التشغيل للتعامل مع المهمة باستخدام الذاكرة الافتراضية ، ولكن يبدو أنها ميؤوس منها. بعد أن تغلبت على العملية ، كان علي الانتظار حوالي دقيقة أخرى قبل أن يبدأ النظام في الاستجابة لأفعالي.

كانت المحاولة التالية عبارة عن مثيل لـ Google Compute Engine ، والذي يسمح لك باستخدام المزيد من ذاكرة الوصول العشوائي (120 جيجا بايت) والمزيد من وحدة المعالجة المركزية (32 سلسلة في 16 وحدة معالجة مركزية). الخبر السار هو أن pbrt كان قادرًا على تقديم المشهد بنجاح (بفضل عمل Heather و Rasmus لتحويله إلى تنسيق pbrt). كان من المثير جدًا أن نرى أن pbrt يمكنه إنشاء وحدات بكسل جيدة نسبيًا لمحتوى فيلم عالي الجودة ، ولكن تبين أن السرعة ليست مذهلة للغاية: 34 دقيقة و 58 ثانية فقط لتحليل وصف المشهد ، وخلال عرض النظام قضى ما يصل إلى 70 جيجابايت من ذاكرة الوصول العشوائي.

نعم ، كان هناك 29 غيغابايت من ملفات وصف المشهد بتنسيق pbrt على القرص والتي تحتاج إلى توزيع ، لذلك لم أكن أتوقع أن تستغرق المرحلة الأولى بضع ثوان. لكن قضاء نصف ساعة حتى قبل أن تبدأ الأشعة بالتتبع؟ هذا يعقد بشكل كبير العمل مع المشهد.

من ناحية أخرى ، أخبرتنا هذه السرعة أن شيئًا كريهًا للغاية ربما يحدث في الكود ؛ ليس فقط "يمكن إجراء عكس المصفوفة بشكل أسرع بنسبة 10٪" ؛ بدلا من ذلك ، شيء على مستوى "أوه ، نحن نمر بقائمة مرتبطة تضم 100 ألف عنصر". كنت متفائلاً وآمل أنه بعد اكتشاف ذلك ، يمكنني تسريع العملية بشكل كبير.

الإحصائيات لا تساعد


أول مكان بدأت فيه البحث عن أدلة هو إحصاءات تفريغ pbrt بعد التقديم. يتم تكوين المراحل الرئيسية لتنفيذ pbrt بحيث يمكنك جمع بيانات ملف التعريف التقريبي عن طريق إصلاح العمليات مع الانقطاعات الدورية أثناء عملية التقديم. لسوء الحظ ، لم تساعدنا الإحصائيات كثيرًا: وفقًا للتقارير ، من حوالي 35 دقيقة قبل بدء العرض ، تم قضاء 4 دقائق و 22 ثانية في بناء BVH ، ولكن لم يتم تقديم تفاصيل حول بقية الوقت.

بناء BVH هي المهمة الحسابية الهامة الوحيدة التي يتم إجراؤها أثناء تحليل المشهد ؛ كل شيء آخر هو في الأساس إلغاء التسلسل الهندسي والأوصاف المادية. معرفة مقدار الوقت الذي تم قضاؤه في إنشاء BVH أعطى فهمًا لمدى فعالية (عدم) النظام: الوقت المتبقي ، أي حوالي 30 دقيقة ، تحليل 29 جيجا بايت من البيانات ، أي أن السرعة كانت 16.5 ميجا بايت / ثانية. تعمل محللات JSON المحسنة جيدًا ، والتي تؤدي نفس المهمة بشكل أساسي ، بسرعة 50-200 ميجابايت / ثانية. من الواضح أنه لا يزال هناك مجال للتحسين.

لفهم الوقت الذي يضيع بشكل أفضل ، أطلقت pbrt باستخدام أداة الأداء Linux التي لم أستخدمها من قبل. ولكن ، على ما يبدو ، تعامل مع المهمة. لقد أمرته بالبحث عن أحرف DWARF للحصول على أسماء الوظائف ( --call-graph dwarf ) ، ولكي لا أحصل على ملفات تتبع 100 جيجا بايت ، اضطررت إلى خفض معدل أخذ العينات من 4000 إلى 100 عينة في الثانية ( -F 100 ). ولكن مع هذه المعلمات ، سار كل شيء على ما يرام ، وقد فوجئت بسرور بأن أداة perf report تحتوي على واجهة مع اللعنات اللطيفة.

إليك ما يمكن أن يخبرني به بعد البدء بـ pbrt:


لم أكن أمزح عندما تحدثت عن "الواجهة بلعنات لطيفة".

نرى أن أكثر من نصف الوقت الذي يقضيه في ميكانيكا التحليل: yyparse() هو yyparse() إنشاؤه بواسطة bison ، و yylex() هو محلل معجم (lexer) تم إنشاؤه بواسطة المرن . يتم قضاء أكثر من نصف الوقت في yylex() على strtod() ، مما يحول السلاسل إلى قيم مزدوجة. yyparse() الهجوم على yyparse() و yylex() حتى المقالة الثالثة في هذه السلسلة ، ولكن يمكننا الآن أن نفهم أنه قد يكون من الجيد تقليل كمية البيانات التي يتم طرحها في جهاز العرض.

من النص إلى PLY


تتمثل إحدى الطرق لقضاء وقت أقل في تحليل البيانات النصية في تحويل البيانات إلى تنسيق يتم تحليله بكفاءة أكبر. معظم ملفات 29 جيجابايت من ملفات وصف المشهد هذه عبارة عن شبكات مثلثية ، ولدى pbrt بالفعل دعم أصلي لتنسيق PLY ، وهو تمثيل ثنائي فعال للشبكات المضلعة. أيضًا في pbrt هناك علامة سطر الأوامر --toply ، والتي تحلل ملف وصف المشهد pbrt ، وتحول جميع شبكات المثلث الموجودة إلى ملفات PLY وإنشاء ملف pbrt جديد يشير إلى ملفات PLY هذه.

المصيد هو أن مواد ptex تستخدم بنشاط في مشهد ديزني ، والتي تتطلب بدورها faceIndex قيمة faceIndex مع كل مثلث ، والذي يحدد وجه الشبكة الفرعية الأصلية المأخوذة منه. لنقل هذه القيم ، كان يكفي فقط إضافة دعم للحقول الجديدة في ملف PLY . وكشفت الأبحاث الإضافية أنه في حالة تحويل كل شبكة - حتى لو كانت تحتوي على عشرات المثلثات فقط - إلى ملف PLY ، يتم إنشاء عشرات الآلاف من ملفات PLY الصغيرة في المجلد ، وهذا يخلق مشاكل في الأداء ؛ تمكنا من التخلص من هذه المشكلة من خلال إضافة القدرة على ترك الشبكات الصغيرة دون تغيير .

لقد كتبت نصًا صغيرًا لسطر الأوامر لتحويل جميع ملفات *_geometry.pbrt في مجلد لاستخدام PLY للشبكات الكبيرة. لاحظ أن لديها افتراضات مشفرة حول المسارات التي يجب تغييرها لكي يعمل البرنامج النصي في مكان آخر.

زيادة السرعة الأولى


بعد تحويل جميع الشبكات الكبيرة إلى PLY ، انخفض حجم وصف المشهد على القرص من 29 إلى 22 جيجا بايت: 16.9 جيجا بايت من ملفات المشهد pbrt و 5.1 جيجا بايت من الملفات الثنائية PLY. بعد التحويل ، انخفض الوقت الإجمالي للمرحلة الأولى من النظام إلى 27 دقيقة و 35 ثانية ، وبلغت المدخرات 7 دقائق و 23 ثانية ، أي أننا تسارعنا 1.3 مرة 3 . تعتبر معالجة ملف PLY أكثر فعالية من معالجة ملف نصي pbrt: تم قضاء 40 ثانية فقط من وقت بدء التشغيل في تحليل ملفات PLY ، ونرى أن ملفات PLY تمت معالجتها بسرعة حوالي 130 ميجا بايت / ثانية ، أو حوالي 8 مرات أسرع من تنسيق نص pbrt .

لقد كان انتصارًا سهلاً جيدًا ، ولكن لا يزال أمامنا الكثير للقيام به.

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

ملاحظات


  1. يجب أن يكون لديك الآن فهم أفضل للدافع لإضافة دعم ptex من جانبي وتحويل Disney BSDF إلى pbrt العام الماضي.
  2. يشار إلى كل الوقت هنا وفي المشاركات اللاحقة لإصدار WIP (العمل قيد التقدم) ، الذي عملت معه قبل الإصدار الرسمي. يبدو أن النسخة النهائية أكبر قليلاً. سنلتزم بالنتائج التي سجلتها عند العمل مع المشهد الأصلي ، على الرغم من أنها لا تتوافق تمامًا مع نتائج النسخة النهائية. أظن أن الدروس المستفادة منها يمكن أن تكون هي نفسها.
  3. لاحظ أن الزيادة في السرعة هي في الأساس ما تتوقعه مع انخفاض بنسبة 50 بالمائة تقريبًا في حجم بيانات التحليل. إن مقدار الوقت الذي نقضيه وفقًا للملف الشخصي يؤكد فكرتنا.

Source: https://habr.com/ru/post/ar417407/


All Articles