Godot: تحسين أداء GDScript عبر تجميع Just-in-time (JIT)

تم إنشاؤها على ٥ يونيو ٢٠١٦  ·  105تعليقات  ·  مصدر: godotengine/godot

ماذا عن اعتماد التجميع في الوقت المناسب (JIT) لـ GDscripts؟

ليس لدى تجميع JIT عيوب على الكود المفسر (بصرف النظر عن بدء التشغيل الأبطأ ، في بعض الحالات) والعديد من المزايا ، خاصة من حيث الأداء.

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

هناك أيضًا خيار استخدام PyPy أو JVM أو CLR ، لكن هذه أثقل جدًا ، باستخدام GNU Lightning أو libjit (لست متأكدًا مما إذا كان الترخيص متوافقًا مع Godot) وبالطبع ، كتابة مولد أكواد من الصفر (والذي يمكن أن يستغرق سنوات).

لذا ، فإن الاختيار هو إلى حد كبير بين LLVM IR و DynASM . يتمتع كلاهما بأداء جيد جدًا ، ولكن DynASM مكتوب بلغة Lua و LLVM له مساحة كبيرة إلى حد ما (حوالي 20 ميجابايت) ، ولكنه يقدم أيضًا ميزات أخرى.

بالطبع ، يمكن أن يكون تجميع GDScript مباشرة إلى C ++ بديلاً صالحًا أيضًا - محرك اللعبة الوحيد الذي أعرفه (إذا فهمته بشكل صحيح) هو Enigma ، الذي يجمع لغة البرمجة النصية الخاصة به (EDL) إلى C ++.

ما رأيك بهذا؟

archived discussion feature proposal gdscript

التعليق الأكثر فائدة

أنا أعمل على تجميع JIT لأطروحة الماجستير وأخطط لتنفيذ شيء يناسب Godot. حتى الآن قرأت في الغالب الكثير من الأوراق حول هذا الموضوع ، وتحديداً حول كيفية التعامل مع الطبيعة المكتوبة ديناميكيًا لـ GDScript. لقد بدأت الآن في العمل على نموذج أولي ، وآمل أن يكون لدي شيء لأظهره قريبًا نسبيًا.

ال 105 كومينتر

تجميع JIT ليس له عيوب على التعليمات البرمجية المفسرة

هناك واحد: قابلية ...

لكن ألن يكون تنفيذ الكتابة الثابتة أفضل وأسهل على الأقل في الوقت الحالي؟ ناهيك عن دعم C # الذي قد يحدث في النهاية؟

Calinou Portability ليس مصدر قلق كبير ، حيث يمكننا فقط تشغيل GDScript كما نفعل الآن على الأنظمة الأساسية غير المدعومة.

يمكن اختيار jitted الكتابة الساكنة أيضا

Calinou قابلية النقل ليست مصدر قلق كبير إذا تم استخدام هذه المكتبات - فهي تدعم الكثير من البنى (ربما يدعم LLVM المزيد من البنى من Godot) وإلى جانب ذلك ، يمكن دائمًا استخدام المترجم كخيار احتياطي (كما قال @ bojidar-bg).

من شأن LLVM IR أن يجعل الكتابة الثابتة أسهل في تبنيها (في النهاية الخلفية ، بالطبع سيظل GDScript بحاجة إلى نوع الاستدلال أو التوقيعات الصريحة).

إذا تم تنفيذ دعم C # عن طريق الربط إما مقابل Mono أو CoreCLR ، فإن كلاهما يشتمل على JITs لذلك سيتم حل هذه المشكلة تلقائيًا. أستطيع أن أفهم لماذا C # (إنها لغة أفضل من Java و Unity تستخدمها بالفعل) ولكن لهذه الأغراض ، من المحتمل أن تحقق JVM أداء أفضل من Mono أو CoreCLR (خاصة بسبب جامع القمامة JVM ، وهو مناسب تمامًا للألعاب لأنه لا يجمد أي شيء). بعد Java 8 ، أنا شخصياً لا أعتقد أن معظم الناس سيعترضون عليها بدلاً من C # (حيث أن المزايا التي توفرها C # في هذه المرحلة تعود في الغالب إلى Generics و LINQ ، وكلاهما ليس مفيدًا في تطوير اللعبة ، وهو أمر ضروري في الغالب) ، واستخدام JVM يتيح الوصول إلى الكثير من اللغات الوظيفية الأكثر إتقانًا من C # مثل Clojure و Scala و Kotlin على أي حال.

كما تجعل LLVM من الممكن استخدام C ++ بأسلوب JITted. يستخدم Unreal Engine أيضًا C ++ للبرمجة النصية ، لذلك لا أعتقد أن هذا سيكون غريبًا جدًا (ستكون السلاسل المقدمة أكثر شيوعًا ، ولكن لا يزال من الممكن تقديم GDScript للمبرمجين الأقل خبرة). C ++ 14 (مدعومة من LLVM في معظمها) هي لغة صغيرة جدًا حتى بالمقارنة مع Java و C # ، إذا تم استخدامها بشكل صحيح (بالطبع ، أوقات الترجمة طويلة ولا تزال رسائل الخطأ ليست جيدة).

سأدعم تجميع JIT لـ GDscript طالما أن ذلك لا يعني نهاية اللغة (أو محررها المضمن) كما هي الآن ،

اقتراحي.

  • أضف نوعًا متغيرًا ثابتًا جديدًا ، والذي يمكن إنشاؤه بدوره عن طريق القيام بشيء مثل
    static var float(5.5) أو شيء ما (سيكون الاختلاف الأساسي هو الأداء العالي والتحليل الأفضل نظرًا لتوقع أن يكون نوعًا معينًا. يجب أن تسمح هذه الطريقة باستخدام الكتابة الثابتة مع الحفاظ على مزايا الكتابة الديناميكية والقضاء على أي حاجة لإعادة كتابة البرامج النصية إذا كنت ترغب في استخدامها
  • بعد ذلك ، قم بإضافة روتين تجميع JIT يحول GDscript إلى C ++ خلف الكواليس (أي غير مرئي للمستخدم) ، لكنه مرئي في شكل أداء عند تشغيل اللعبة. إن فكرة استخدام C ++ هنا تعني أن مطوري Godot لن يضطروا إلى إضافة مجموعة من المكتبات الجديدة إلى المصدر.

يتم تنفيذ JIT في اللغات المكتوبة ديناميكيًا مثل Lua عن طريق إجراء الاستدلال على الكتابة
من نقطة الدخول عبر شجرة الاتصال ، بالتعمق قدر الإمكان. انا
عدم قول هذا لن يكون ممكناً في Godot ، مثل كل إدخال تقريبًا
يتم كتابة النقطة. يقوم إكمال الكود في Godot بعمل شيء مشابه ، وهو
هو سبب قدرته على تخمين الكثير من معلومات الكتابة.

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

للمساعدة في ذلك ، سيكون من السهل السماح لـ GDScript للسماح للمستخدم بذلك
"فرض" نوع المتغير (شيء غير ممكن في lua). ولكن إذا كنت
ستفعل ذلك ، فيمكنك أيضًا الانتقال إلى الكتابة الثابتة الكاملة.

لست مقتنعًا بأي نهج في الوقت الحالي.

في يوم الأحد ، 5 حزيران (يونيو) 2016 الساعة 5:37 مساءً ، كتب Ace-Dragon [email protected] :

سأدعم ترجمة JIT لـ GDscript طالما أنه لا يعني ذلك
نهاية اللغة (أو محررها المدمج الخاص بها) كما هي الآن ،

اقتراحي.

  • أضف نوع متغير _static_ جديد ، والذي بدوره يمكن إنشاؤه بواسطة
    طريقة عمل شيء مثل
    static var float (5.5) أو شيء من هذا القبيل (سيكون الاختلاف الأساسي
    أداء أعلى وتحليل أفضل نظرًا لتوقع أن يكون
    نوع خاص أو معين. يجب أن تسمح هذه الطريقة باستخدام الكتابة الثابتة أثناء
    الحفاظ على مزايا الكتابة الديناميكية والقضاء على أي حاجة لها
    إعادة كتابة البرامج النصية إذا كنت ترغب في استخدامها
  • بعد ذلك ، قم بإضافة إجراء ترجمة JIT يقوم بتحويل GDscript إلى
    C ++ خلف الكواليس (أي غير مرئي للمستخدم) ، لكنه مرئي في النموذج
    من الأداء عند تشغيل اللعبة. فكرة استخدام C ++ هنا تعني
    أن مطوري Godot لن يضطروا إلى إضافة مجموعة من المكتبات الجديدة إليها
    المصدر.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment -223836149 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe/AF-Z2znHs58L-KDgtIjHYYjgHVUGXgwpks5qIzOngaJpZM4IuWZe
.

يستخدم Haxe استدلال الكتابة على الرغم من أنه آمن من النوع تحت الغطاء. أنا شخصياً أحب حقيقة أنه لا يتعين علي تحديد نوع كل متغير ولكن يمكنك القيام بذلك إذا كنت بحاجة إليه. بهذه الطريقة يكون لديك أفضل ما في العالمين: لست بحاجة إلى تحديد الأنواع (طالما أن المترجم يمكنه اكتشافها) وكتابة طرق "عامة" / "نموذجية" ينتج عنها بناء جملة أكثر نظافة كما هو الحال في اللغات المكتوبة بشكل ثابت مثل C ++ أو C # ، ولكن بشكل فعال ، يكون الرمز آمنًا ويمكنك تحديد النوع المطلوب متى أردت استخدامه لجعل الكود أكثر قابلية للقراءة.

في Haxe يتم ذلك باستخدام بناء الجملة
var <name> [: <Type>] [=<initial value>]
التي تبدو غريبة جدًا من اللغات المكتوبة ولكنها منطقية تمامًا لأنها تأتي من لغة مثل GDScript.

لكن ليس لدي أي فكرة عن كيفية تأثير ذلك على تعقيد وفعالية تجميع JIT ، أردت فقط أن أشير إلى أن هذا سيكون نوعًا من الحل الوسط بين الكتابة الديناميكية كما هي الآن والكتابة الثابتة الكاملة كما هي في لغات مثل C ++.

لقد استخدمت Haxe لمدة 1 إلى 2 سنوات منذ فترة طويلة.
أحب أن أكون قادرًا على تحديد النوع اختياريًا لإرجاع المتغير والوظيفة كما قال Warlaan .

أفضل أسلوب إعلان نوع c ++ قبل الكتابة المطبوعة / haxe:

var x = 50
int y = 60
float z =70

أو ربما يمكننا عكس نمط export :

type(int) var y = 60
type(float) z =70

@ bojidar-bg أنا شخصياً أفضل أسلوب c ++ أكثر (أقل بكثير في الكتابة).

هناك الكثير من المشكلات التي يمكن أن تنشأ عن وضع النوع قبل المتغير. كتب Go من قبل بعض أكثر منفذي C خبرة على الإطلاق (بما في ذلك Ken Thompson) وذهبوا مع تدوين Postfix (مثل Pascal و Haxe).

أعتقد أن هذه المناقشة تنتمي إلى مناقشة منفصلة. أنا لا أقترح تصويتًا لأن معظم الناس بالطبع معتادون على لغات مكتوبة مثل C ++ و C # و Java ويمكنهم التصويت على بناء الجملة المألوف ولكن فقط لجمع المواد البحثية والآراء للعثور على الحل الأنسب للغة مثل GDScript (والذي من الواضح أنه لا يشبه C في أي جانب آخر).

أوافق في جميع الجوانب الأربعة:

  1. لغة C ++ - هي أجمل للقراءة ، ولكن
  2. imho تدوين postfix أكثر منطقية هنا
  3. الذي أفضل مناقشته (لا أقرر بالأغلبية)
  4. في موضوع آخر. عذرًا ، لم أقصد اختطاف الموضوع عندما ذكرت الموضوع. دعنا نعود إلى مسألة تجميع JIT.

هل تنفيذ JIT عبر LLVM يعني أنه سيتم تفضيل Clang على دول مجلس التعاون الخليجي. هل من الممكن تجميع LLVM JIT باستخدام GCC؟

على عكس Java و Python و C # وما إلى ذلك ، يعمل GD Script كجزء من محرك شفرة أصلي أكبر لـ C ++. في الواقع ، يعتبر كل من GD Script وبقية المحرك وحدة واحدة. بعض مكونات اللعبة هي C ++ وبعضها GD Script. بشكل عام ، يعتمد أداء اللعبة على خلق توازن بين الاثنين. إن كتابة لعبة Godot في النص فقط سيجعلها أبطأ ، لكن كتابتها في الغالب عبر عقد بأقل نص من gd سيجعلها أسرع.

لذا سؤالي هو. هل هذه الزيادة الطفيفة في الأداء تستحق العناء حقًا؟

أعتقد أن إضافة C # قد تكون في الواقع أفضل للمحرك من تنفيذ JIT في GD Script. من المحتمل أن تكون C # لغة محسّنة وفعالة بدرجة أكبر ، وبالتالي من المحتمل أن تكون سريعة مثل GD Script + JIT ولكنها ليست متكاملة مثل GD Script.

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

هل تنفيذ JIT عبر LLVM يعني أنه سيتم تفضيل Clang على دول مجلس التعاون الخليجي. هل من الممكن تجميع LLVM JIT باستخدام GCC؟

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

لا أعتقد أن التعزيز في الأداء سيكون ضئيلًا بالنسبة للألعاب الأكبر حجمًا. ربما لن يكون الأمر ملحوظًا بالنسبة لألعاب الأركيد ، ولكن في الألعاب التي تحتوي على الكثير من الحلقات والمكالمات الوظيفية ، سيكون ذلك بالتأكيد.

أيضًا ، هل هناك مناقشة حول سبب استخدام C # عبر Java أو حتى C ++؟ أعتقد أن C # هي لغة جيدة جدًا ، لكن CLR والأدوات هي بالتأكيد أدنى من JVM (خاصة على الأنظمة الأساسية الأخرى غير Windows).

@ paper-pauper ، يجب عليك إنشاء منشور في المنتدى حول Java ، JIT لمواصلة هذه المناقشة. أنا في الواقع أفضل Java> C # tbh. أعتقد أن C # لم يكن خيارًا ولكنه كان فرصة قررت مطوري البرامج اغتنامها.

لذلك قررنا في النهاية؟ سوف JIT أم لا؟

ماذا عن القدرة على ترجمة GDScript إلى كود C ++ ثابت؟ هل هذا ممكن حتى؟

trollworkout : ربما يكون من الأسهل والأمثل كتابة منطق لعبتك مباشرة في C ++ إذن ، أليس كذلك؟

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

trollworkout بفضل # 3936 ، قد يكون من الممكن تجميع GDScript إلى C وتحميلها ديناميكيًا ، في النهاية.

ليس من الضروري ترجمة البرنامج النصي في c ++. SuperUserNameMan حقوق

أو تحتاج JIT أو c # وسيكون الجميع سعداء

nah الموضوع الآخر @ paper-pauper المرتبط هو في الواقع أكثر إثارة للاهتمام. تكمن الفكرة في استخدام ثنائي C كنوع من لغة البرمجة النصية ورمز الاتصال مباشرة عبر الانعكاس بدلاً من تفسيره ، مما يجعله سريعًا مثل رمز C ++ الأصلي الذي أعتقد أنه من شأنه أن يحل مشكلة ABI. في الواقع مع هذا لن تحتاج إلى ABI بعد الآن.

أقوم حاليًا بتجربة تنفيذ GDScript JIT باستخدام RPython. النتائج الأولى (الأولية للغاية) واعدة ، لكنني لا أعرف مدى صعوبة دمجها في المحرك.

هل لا يزال هناك اهتمام بـ JITed GDScript أم أن الأشخاص أكثر إثارة للاهتمام في C # أو GDScript الثابت؟

بالنظر إلى أنك تحاول بالفعل حلًا ممكنًا ، فأنا أقول لك أن تفعل ذلك ومعرفة ما إذا كان هناك مكاسب كافية في الأداء في الألعاب تستحق العناء.

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

الأداء مهم بالنسبة لي ، لا يمكنني اختيار Godot للسيناريو
أداء. لكنني أعتقد أن اللغة الأسرع (Lua ، Java ، c #) أفضل من Jit ، لأن Jit لا تعمل على iOS. ويفقد التجميع إلى ++ C إمكانية تحديث منطق اللعبة على iOS

أليس Lua أسرع فقط بسبب JIT؟ أم أنه يحتوي على نوع من تجميع AOT أيضًا؟

ما زلت أفضل GDScript مكتوبًا بشكل ثابت (ربما يكون نظام كتابة اختياريًا ، مثل TypeScript مخصص لجافا سكريبت). كما أن وجود GDScript -> ترجمة C ++ من شأنه أن يحل الكثير من مشكلات الأداء ، لكن يمكنني أن أرى أن هذا بعيد كل البعد عن التافه.

كيف تقوم بتحديث منطق اللعبة في iOS؟ لا يمكنك تنزيل البرامج النصية من
ألعابك وتشغيلها على iOS ، يجب تثبيت كل شيء من ملف
ipa الأصلي الذي تم نشره في متجر التطبيقات. في كلتا الحالتين عليك
قم بتحديث التطبيق للحصول على منطق جديد أو حدث إذا كان نصوصًا جديدة أو وقت تشغيل جديد
مع المنطق المترجم في.

في 20 أغسطس 2016 الساعة 05:05 ، كتب George Marques [email protected] :

أليس Lua أسرع فقط بسبب JIT؟ أم أنه يحتوي على نوع من AOT
تجميع أيضا؟

ما زلت أفضل GDScript مكتوبًا بشكل ثابت (ربما كتابة اختيارية
النظام ، مثل TypeScript مخصص لجافا سكريبت). وجود GDScript أيضًا -> C ++
قد يحل الترشيح الكثير من مشكلات الأداء ، لكن يمكنني رؤية ذلك
أبعد ما يكون عن التافه.

-
أنت تتلقى هذا لأنك مشترك في هذا الموضوع.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment -241175124 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AGVmPZDOcIkO1-6ayDySyPnCfJdRk5Saks5qhm76gaJpZM4IuWZe
.

سيكون GDScript المكتوب بشكل إحصائي مع VM المحسن جيدًا أيضًا ، هل هناك أي خطة لذلك؟

نظام الكتابة الاختياري لـ GDScript كما اقترح vnen سيكون مثاليًا :)

أثناء البحث عن هذا ، وجدت SLJIT العظيم. لقد كنت أحاول معرفة كيف يمكنني دمجها للسماح بتجميع JIT على الأقل على مستوى وظيفة GDScript.

بعد بضع ساعات من القراءة / التفكير ، توصلت إلى استنتاج مفاده أنه لن يكون ذا فائدة تذكر لأن أكبر عنق زجاجة ، الآن لقد درست الكود بعمق ، ربما يكون كل الأشياء Variant .

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

لذلك ألخص نفسي للمجموعة التي تعتقد أن الكتابة الثابتة ستزيل الكثير من الاتصال والتفرع وبالتالي تحسين الأداء بشكل ملحوظ.

تضمين التغريدة

أوافق على أن JIT غير ممكن حاليًا ، لكن المشكلة هي Variant وليست الكتابة الديناميكية.

لقد جربت كتابة GDScript JIT باستخدام RPython ، وهو أساس PyPy ومصمم خصيصًا لإنشاء JITs للغات الديناميكية.

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

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

إذا كان لدى أي شخص فكرة عن كيفية تدبير الأمور دون استخدام المتغيرات ، فسيكون من الممكن الحصول على GDScript سريع (دليل على مفهوم GDScript JIT الخاص بي والذي لم يستخدم Variant كان واعدًا. الحلقة (السخيفة) التي استغرقت 20 ثانية في GDscript كانت تم في أقل من ثانية عندما JITted)

حسنًا ، كنت أعامل الكتابة المتغيرة والديناميكية كما لو كانت كلاهما متماثلًا
شيء أو كما لو أن أحدًا لا يمكن أن يكون بدون الآخر.

لكن ربما أفتقد شيئًا ما في تصميم اللغة.

تتيح AIUI Variant استخدام C ++ في Godot كما لو كانت لغة مكتوبة ديناميكيًا. خاصة في نوع الإرجاع لبعض الطرق. لست على دراية بالمصدر ، لكنني لست متأكدًا مما إذا كانت هناك طريقة نظيفة للتغلب عليه.

brakhane الرعاية لتبادل تجربة RPython الخاص بك؟ أعتقد أن الجميع هنا سيستفيدون من إلقاء نظرة عليه: ابتسم:

المتغير متأصل بعمق في Godot ومع ذلك ، فمن الصعب حقًا الاستغناء عنه. سأضطر إلى إعادة تنفيذ جميع أنواع بيانات GDScripts والتحويل إلى المتغيرات بعد ذلك.

من الناحية النظرية ، ما هو العيب في ذلك (بصرف النظر عن الوقت اللازم لتنفيذه)؟ هذا النوع من الاختيار ليس باهظ الثمن ، بقدر ما أفهمه.

@ paper-pauper ، انظر إلى PyPy و RPython - يتم كتابة Python ديناميكيًا بدقة ، ويمكن لـ PyPy تسريع كود Python مدروس جيدًا ... RPython مفيد جدًا لتطوير المترجمين الفوريين (مع JIT شبه خالية)

تم نشر مقال مثير للاهتمام حقًا (قيد التطوير حاليًا) جديد Ruby JIT.

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

في الأساس ميزة الاستخدام والمترجم الخارجي (على عكس دمج إطار عمل JIT) هي:

  • الاستقلال لمترجم واحد (يمكن استخدام GCC أو LLVM اعتمادًا على ما هو متاح / أفضل)
  • تعد أطر عمل JIT مثل libGCCJit حديثة العهد لذا يمكن أن تكون واجهة برمجة التطبيقات الخاصة بها أكثر هشاشة من C

بالطبع يجب اتخاذ هذا مع الكثير من الاحتياطات (تقارن مقاييس المقالة نموذجًا أوليًا بمشاريع جاهزة للإنتاج مثل JRuby) ، لكنها توضح أنه ، شريطة استخدام تحسينات ذكية مثل الرؤوس المجمعة مسبقًا ، يمكن أن يكون استخدام مترجم خارجي حل قابل للحياة.

من وجهة نظر جودو ، يمكن أن تكون هذه التقنية مفيدة أيضًا لتوفير تجميع ثابت لـ GDscript.

أنا أعمل على تجميع JIT لأطروحة الماجستير وأخطط لتنفيذ شيء يناسب Godot. حتى الآن قرأت في الغالب الكثير من الأوراق حول هذا الموضوع ، وتحديداً حول كيفية التعامل مع الطبيعة المكتوبة ديناميكيًا لـ GDScript. لقد بدأت الآن في العمل على نموذج أولي ، وآمل أن يكون لدي شيء لأظهره قريبًا نسبيًا.

DoctorAlpaca لقد انتهيت تقريبًا من عمليات التحقق من النوع الثابت لـ GDScript ، أعتقد أن هذا قد يساعدك قليلاً على الأقل (يمكنك البحث عن مفترقتي إذا كنت مهتمًا ، وكذلك # 10630). كنت أخطط للنظر في JIT في النهاية ، لكن ليس لدي أي خبرة في ذلك.

منذ بعض الوقت بدأت تجربة حول JIT-ting GDScript. لقد قمت بإعداد بعض foudation لذلك.
في حال كنت تريد إلقاء نظرة ... https://github.com/RandomShaper/godot/tree/exp-gdscript-jit-master

vnen أنا في الواقع متحمس جدًا لمعرفة مقدار الاختلاف في الكتابة الثابتة في الأداء التي يمكن أن

RandomShaper هذا الإعداد يبدو لطيفًا ، وبعد النظر في الخيارات المتاحة ربما سأختار SLJIT أيضًا. شكرا على ذلك!

وصلت نتائج استطلاع مايو 2018 ، ويبدو أن هذا الاقتراح يحتل أولوية خارطة الطريق.

أنا شخصياً لا أعتقد أن JIT GDScript ستكون فكرة جيدة:

  • JIT غير مسموح به على الأنظمة الأساسية للجوّال (على الأقل على IOS ، لست متأكدًا من Android) ، والتي هي الأكثر حاجة إلى هذا النوع من التحسين ...
  • JIT هو فوضى كبيرة. هناك طرق متعددة (التتبع مقابل طريقة JIT) ، بعضها ليس حتميًا: '- (
  • JIT هو فوضى كبيرة كبيرة. التصحيح معقد (يتضمن تفريغات للشفرة والذاكرة المؤقتة ...) ، وكذلك التنميط ، وكذلك الحفاظ على الكود: '- (
  • JIT هو نوع خاص من الفوضى. يعد مبرمجو JIT موردًا نادرًا ، لذا فإن الحفاظ على مثل هذا الشيء سيكون أمرًا صعبًا. قد يؤدي هذا إلى جعل تطوير GDScript يصبح أكثر صعوبة لأن المترجم الفوري و JIT سيكونان مرتبطين بإحكام.

يوضح مشروع luaJIT جيدًا تلك النقاط: المشروع ببساطة رائع (قاعدة الشفرة جيدة حقًا ، وأداء جيد جدًا) ، وهو يحل حالة استخدام حقيقية ، ويتم استخدامه من قبل الشركات التجارية.
ومع ذلك ، فإنها تموت ببطء نظرًا لأن المؤلف الرئيسي قد تراجع إلى الوراء ، غير قادر على مواكبة إصدار lua الجديد (توقف luaJIT عند 5.1 ، بحجة أن إضافة عدد صحيح أعلى عدد عشري في اللغة التي تم إجراؤها بواسطة 5.2 سيكون أمرًا معقدًا حقًا add) ، حتى لو كان مجتمع lua متوسط ​​الحجم و luaJIT هو أفضل مشروع معروف.

من الواضح أن GDScript هو ترتيب من حيث الحجم أبسط من Python أو حتى lua ، لكن عبء إنشاء JIT يظل مهمًا ، لا سيما بالنظر إلى أنه ليس سمة أساسية لمشروع Godot.

الحل الوحيد المقبول هنا هو الاعتماد على llvm الذي سيهتم بجميع الأجزاء المجنونة ودعنا نخرج رمز llvm-ir إليه. ومع ذلك ، كما قيل من قبل ، فإن llvm هو تبعية كبيرة (في هذه المرحلة يمكننا تقريبًا شحن الإصدار 8 مع Godot وكتابة GDScript إلى Javascript transpiler بدلاً من ذلك: trollface :) ، لذا يلزم إجراء بحث إضافي لفهم المقدار الذي سيتم إضافته هنا قبل الانتقال في أى مكان. ومرة أخرى ، لن يكون هذا حلاً قابلاً للتطبيق على الأقل لمنصة IOS (اللعنة عليك Apple!).

يؤسفني أن أبدو كئيبًا للغاية هنا ، لكنني لن أنشر هذا بدون اقتراح ؛-)
أعتقد أن ما يفهمه ناخبو الاقتراع من خلال "JIT GDScript" هو "GDScript ، ولكن سريعًا كالشفرة الأصلية". إذن في النهاية ، لا يهم حقًا ما يعنيه الوصول إلى هذا الهدف بشكل صحيح (AOT ، JIT ، transpiling + compilation وما إلى ذلك)؟

مما رأيته في GDScript ، فإن الميزة الرائعة (نقص) هي أنها ليست لغة ديناميكية. لا توجد كلمة رئيسية exec ، ولا توجد ترقيع للقرد ، ولا يمكنك تعديل المتغير أثناء التصحيح وما إلى ذلك.
هذا يجعل اللغة مناسبة للترجمة الثابتة (وفي الحقيقة يعد هذا سببًا إضافيًا لعدم استخدام JIT). علاوة على ذلك ، يجب أن يسمح نظام الكتابة الثابت الجديد بالتحسين السهل (مقارنة بضرورة القيام بالاستدلال على الكتابة).

لذا فإن فكرتي هي أن أبدأ بعمل ناقل بسيط (بدون تحسينات ، فقط استخدم Variant في كل مكان) GDScript-to-C transpiler ، والذي سيكون متاحًا كـ godot --gdcc <myfile.gd> . إن استخدام مترجم GDScript الحالي وواجهة برمجة تطبيقات GDNative سيجعل هذا الأمر سهلاً نسبيًا.
يُترك المستخدمون بعد ذلك للتعامل مع بقية سلسلة الأدوات (على سبيل المثال ، تجميع كل ملف C كملف.

في المرة الثانية ، يمكننا البدء في التساؤل عن التحسينات ، والأهم من ذلك ، طريقة إرسال مترجم إلى Godot.
بالنظر إلى هذه النقطة الثانية ، يبدو tinycc حلاً مثيرًا للاهتمام حقًا نظرًا لوزنه الخفيف ، فهو عدد الأنظمة الأساسية المدعومة (x86 و amd64 و arm و arm64 لنظام التشغيل Linux و Win32 و OSX) ، وهو libtcc.h api الذي يسمح بدمجه في برنامج ويعبر وضع الترجمة. علاوة على ذلك الإصدار 0.9.27 تم إصداره في ديسمبر الماضي (لذلك يبدو المشروع على قيد الحياة ^^).

أخيرًا ، بالطريقة نفسها التي نحول بها حاليًا ملفات .gd إلى .gdc أو .gde في وقت التصدير ، يمكننا إنشاء نوع جديد (.gdso؟) لن يكون سوى نص عادي أصلي (لذا فإن محمل موارد GDNative سيستدعي Nativescript عليه تلقائيا).

أوافق على أنه سيكون من المبالغة كتابة مترجم JIT لـ GDScript. كما ذكرت ، لا يُسمح بتجميع JIT على نظام التشغيل iOS (يسمح Android بذلك) ، لذلك سيكون عليك إما الرجوع إلى التفسير البطيء على تلك المنصة أو كتابة مترجم AOT (انظر! الآن عليك الاحتفاظ بمجمعين بالإضافة إلى المترجم).

لقد قلت مرات عديدة أنني أعتبر أن برنامج التحويل الصوتي GDScript2C هو الخيار الأفضل الآن بعد أن أصبح لدينا GDNative.

بالنسبة للثنائيات التي تم إنشاؤها باستخدام الوحدة الأحادية ، يمكنك كتابة مترجم GDScript2IL وبعد ذلك سيكون لديك كل من JIT و AOT compilation.

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

في الواقع ، في GDScript ، يمكنك تعديل التعليمات البرمجية المصدر لبرنامج نصي في وقت التشغيل.

في الواقع ، في GDScript ، يمكنك تعديل التعليمات البرمجية المصدر لبرنامج نصي في وقت التشغيل.

neikeq لقد بحثت عن هذا قبل كتابة رسالتي ، أعتقد أنني لم أبدو قريبًا بما يكفي ^^
هل يمكنك أن تدلني على مثال؟ (أو حيث يتم تنفيذه في مصدر البرنامج)

في الواقع ، في GDScript ، يمكنك تعديل التعليمات البرمجية المصدر لبرنامج نصي في وقت التشغيل.

ليس بقدر "تعديل". يمكنك تعيين خاصية source_code للنص البرمجي برمز جديد بالكامل ثم استدعاء reload() لإعادة تجميعه. من الناحية الفنية ، يتم تنفيذ هذا أيضًا لـ C # ، لأنه جزء من Script API.

touilleMan فكرتك مشابهة لما تمت مناقشته في # 11068.

مشكلة تحويل GDScript ، أو تجميعها مسبقًا ، هي أنه حتى مع نظام النوع الثابت ، لا يزال يتعين أن تكون جميع استدعاءات الطرق افتراضية. أي شيء يمكن أن يختبئ خلف معلمة Node . لذلك ستواجه مشكلات أداء مشابهة مثل Java ، والتي تستخدم JIT على كودها الثانوي (جزئيًا) لنفس الأسباب.

على أي حال ، نظرًا لأنني بحاجة إلى جزء عملي لأطروحة الماجستير الخاصة بي ، فسوف أقوم بتطبيق JIT لـ GDScript على أي حال ، لذلك بعد ذلك يمكننا أن نرى مدى نجاحها ومدى تدميرها لقاعدة الكود. أنا بصراحة لا أمانع حتى لو ظل نموذجًا أوليًا إلى الأبد ولم يتم دمجه أبدًا.

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

vnen الكود المصدري في C # يستخدم فقط للبرمجة. لم يتم تجميعها على reload .

تضمين التغريدة

بالنظر إلى هذه النقطة الثانية ، يبدو tinycc حلاً مثيرًا للاهتمام حقًا نظرًا لوزنه الخفيف ، فهو عدد المنصات المدعومة (x86 و amd64 و arm و arm64 لنظام التشغيل Linux و win32 و osx) ، وهو libtcc.h api الذي يسمح بدمجه في برنامج وعبر وضع الترجمة. علاوة على ذلك الإصدار 0.9.27 تم إصداره في ديسمبر الماضي (لذلك يبدو المشروع على قيد الحياة ^^).

فكرة سيئة ، المشروع على الأرجح ميت أكثر منه على قيد الحياة!

تضمين التغريدة

بالنسبة للثنائيات التي تم إنشاؤها باستخدام الوحدة الأحادية ، يمكنك كتابة مترجم GDScript2IL وبعد ذلك سيكون لديك كل من JIT و AOT compilation.

لكن هذا خيار مثير للاهتمام. وربما يمكن مقارنتها بتكاليف العمالة مع إضافة JIT.

بشكل عام ، إذا كان هناك بالفعل شخص سوف يشارك في هذا على أي حال ، فدعه يفعل ذلك. الفريق لا يخسر من هذا. أقترح الاسترخاء والانتظار ، فجأة سيظهر شيء ما (على الرغم من أنني لا أعول عليه)

DoctorAlpaca مع الأخذ في الاعتبار الطريقة الافتراضية للإرسال ، أعتقد أن الأمور بالفعل بهذه الطريقة عند استخدام واجهة برمجة تطبيقات C ++. إذن هدفك هنا هو جعل GDScript أسرع من C ++؟ ؛-)
على أي حال ، أنا آسف إذا ظهرت لك رسالتي السابقة بأسلوب "إنه عديم الفائدة ، لا يجب أن تفعله".
تعد التجربة أكثر قيمة من الافتراض بشكل كبير ، لذا لا يمكنني إلا أن أؤيدك ليس هذا ، علاوة على ذلك ، هناك فرص كبيرة لأن عملك سيجلب لك تحسين جزء مختلف من المحرك (إصلاح الأخطاء ، التنظيف ، أو حتى البحث عن تحسينات لـ- نظام متغير ديناميكي إلى سريع) لذلك لا يضيع شيء أبدًا!
راجع للشغل إذا كنت مهتمًا حقًا بـ JIT ، أقترح عليك القدوم إلى Europython (نهاية يوليو في إدنبرة ، سأكون هناك ^^) ، يتواجد فريق Pypy كل عام ويمكنك إجراء البرمجة السريعة على Pypy معهم خلال عطلة نهاية الأسبوع بأكملها. عادة لا يوجد الكثير من الناس وهم حقاً طيبون وتربويون ، لذا فإن الأمر يشبه في الأساس أخذ فصل دراسي لمدة يومين في JIT مع خبراء عالميين ؛-)

@ ret80 أوافق على أن مشروع tinycc ليس نشطًا حقًا. من ناحية أخرى ، نحن نتحدث عن مترجم C ، لا يزال المعيار الأكثر استخدامًا هو C99 (مع استمرار وجود C89 بالفعل) لذلك لا يوجد الكثير من التطورات التي يمكن القيام بها بمجرد استقرار المشروع بدرجة كافية (أعتقد أنه يمكننا القول أنه يمكن تحقيق التطورات في التحسين ، ولكن هذا من المرجح أن يضيف إلى حجم وسرعة المترجم ، لذلك ليس هدف هذا المشروع).
أكثر ما يقلقني بالنسبة لهذا المترجم هو دعم معماريات الذراع و.
أخيرًا ، نظرًا لأننا سنستخدم هذا المترجم مع رمز مُنشأ تلقائيًا (دائمًا نفس الإنشاءات و gdnative مثل التبعية الفردية) ، يجب أن نكون آمنين نسبيًا حتى لا نصل إلى الأخطاء المخفية بمجرد أن يكون المشروع على المسار الصحيح.

neikeq أجد فكرة استخدام وقت التشغيل الأحادي لـ JIT أنيقة حقًا! سيؤدي ذلك إلى تقليل عدد التبعيات (وتحسين عدد الأشخاص المشاركين في الوحدة الأحادية التي تكون دائمًا أفضل) وسيوفرون علينا إصدار إصدار آخر.

بصراحة لن أفكر في JIT بل أجمع AOT. سيكون شيئًا مثل TerraLang (واجهة lua أمامية لـ LLVM مصممة لبناء اللغات ديناميكيًا) مفيدًا لكل من تطوير إعادة التحميل السريع للمصدر وكذلك التجميع إلى كائنات أصلية ثنائية لربط التجميع (بدون ترجمة ، تم تجميع LLVM) سيكون مفيدًا مثل سيكون من التافه إلى حد ما التخصص حتى لأنواع محددة من العقد. من المحتمل أن تظل النفقات الظاهرية مشكلة ولكنها ستكون أسرع بكثير مما هي عليه الآن ، خاصة بمجرد بدء كتابة المعلومات. أنا شخصياً قمت فقط بتضمين LLVM في المحرر / المترجم ، نعم سيزيد الحجم ولكن هذا يعني أيضًا أن الألعاب نفسها قد ينتهي بها الأمر أصغر ، خاصة إذا قمت بتضمين ملفات الكائنات و / أو مصدر godot مع المحرر والسماح إنها LTO كل ذلك في إخراج نهائي أصغر وأسرع.

يوضح مشروع luaJIT جيدًا تلك النقاط: المشروع ببساطة رائع (قاعدة الشفرة جيدة حقًا ، وأداء جيد جدًا) ، وهو يحل حالة استخدام حقيقية ، ويتم استخدامه من قبل الشركات التجارية.
ومع ذلك ، فإنها تموت ببطء نظرًا لأن المؤلف الرئيسي قد تراجع إلى الوراء ، غير قادر على مواكبة إصدار lua الجديد (توقف luaJIT عند 5.1 ، بحجة أن إضافة عدد صحيح أعلى عدد عشري في اللغة التي تم إجراؤها بواسطة 5.2 سيكون أمرًا معقدًا حقًا add) ، حتى لو كان مجتمع lua متوسط ​​الحجم و luaJIT هو أفضل مشروع معروف.

لست متأكدًا من أنني سأسميها ميتة ، فقد تم تشعبها على جيثب منذ فترة طويلة ويتم تحديثها إلى إصدارات LUA الحديثة وما إلى ذلك.

أجد فكرة رائعة لاستخدام وقت التشغيل الأحادي لـ JIT! سيؤدي ذلك إلى تقليل عدد التبعيات (وتحسين عدد الأشخاص المشاركين في الوحدة الأحادية التي تكون دائمًا أفضل) وسيوفرون علينا إصدار إصدار آخر.

لا يزال غير مسموح به على نظام iOS وما إلى ذلك.

ما زلت أعتقد أنه يجب دمج فكرة JIT مع GDNative بطريقة ما بحيث يتم تجميع GD Script مسبقًا نوعًا من كود التشغيل C الخاص بالطرف الثالث ويجب أن يكون GDNative قادرًا على تحليل كود التشغيل هذا وترجمته إلى كود C ++.

@ OvermindDL1 شكرًا جزيلاً على ذكر TerraLang ، يبدو أنه مشروع مثير للاهتمام حقًا ؛-)

لست متأكدًا من أنني سأسميها ميتة ، فقد تم تشعبها على جيثب منذ فترة طويلة ويتم تحديثها إلى إصدارات LUA الحديثة وما إلى ذلك.

أنا لست قريبًا حقًا من مجتمع lua ، لذا فقد يكون فهمي خاطئًا بشأن هذا الموضوع. هل يمكنك أن تدلني على النسخة المتشعبة من luaJIT التي تنفذ إصدارات lua الجديدة؟

@ OvermindDL1 شكرًا جزيلاً على ذكر TerraLang ، يبدو أنه مشروع مثير للاهتمام حقًا ؛-)

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

حتى مع الأخذ في الاعتبار ذلك ، إذا كنت سأكتب مترجمًا خلفيًا أصليًا لـ GDScript ، فمن المحتمل أن أستخدم أحدث إصدار من LLVM's C ++ API. واجهة برمجة تطبيقات C مستقرة ، لكن واجهة برمجة تطبيقات C ++ لديها الكثير من القوة والكثير من الطاقة اللازمة لتطبيق لغة وليس فقط المسح ، خاصة إذا كنت ترغب في استخدام libclang لمجموعة التحسين الكاملة. ومع ذلك ، فإن TerraLang يعمل بشكل كامل بهذه الطريقة أيضًا وهو أسهل في الاستخدام بشكل ملحوظ إذا كان أقل اختبارًا واستخدام إصدار LLVM أقدم (C ++ API ، على الرغم من أنهم يريدون التحديث ، لذلك بالطبع نرحب بالعلاقات العامة).

أنا لست قريبًا حقًا من مجتمع lua ، لذا فقد يكون فهمي خاطئًا بشأن هذا الموضوع. هل يمكنك أن تدلني على النسخة المتشعبة من luaJIT التي تنفذ إصدارات lua الجديدة؟

ركضت عبر اثنين من الأشياء المثيرة للاهتمام على https://github.com/LuaJIT/LuaJIT/network في وقت ما ، لقد تم تشعبها عدة مرات وهناك الكثير من أعمال التطوير التي تحدث على عدد قليل من الشوكات الكبيرة. أنا لست كبيرًا حقًا في مجتمع Lua أيضًا ، فأنا أقوم بتطبيق luajit في عدد قليل من المشاريع للحصول على دعم البرمجة النصية ولكن لا أكتب حقًا lua بنفسي (يبدو أن lua لديها مدير حزم في الوقت الحاضر ، luarocks أو شيء من هذا القبيل). لقد مررت عبر شوكة كبيرة أو اثنتين من luajit التي لم يتم تشعبها مباشرة من luajit repo أيضًا (لذلك لن تظهر في تلك القائمة) ، وأعتقد أن أكبر ما رأيته لم يكن مدرجًا في تلك القائمة .. .

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

بدأت مؤخرًا العمل على JIT لـ GDScript باستخدام RPython (مجموعة الأدوات التي يستخدمها PyPy لإنشاء JIT الخاصة بهم) ، وقد بحثت في استخدام LLVM كبديل أيضًا.

لجعل قصة طويلة قصيرة: LLVM ليست مناسبة لـ JIT ، لقد قرأت عددًا قليلاً من منشورات المدونة التي وصلت إلى هذا الاستنتاج ، ويبدو أن تجربتي معها تؤكد ذلك أيضًا. هناك سببان رئيسيان:

  1. LLVM بطيء. لا أقصد الكود الذي تم إنشاؤه بواسطة LLVM ، أعني أن الوقت الذي يستغرقه LLVM لإنشاء هذا الرمز يخلق عنق الزجاجة لـ JIT. تحول Webkit JIT من LLVM إلى حل البيرة ، وكان هذا أحد الأسباب

  2. تفترض LLVM أن الكود الخاص بك مكتوب بشكل ثابت ، وهو مناسب تمامًا لتجميع اللغات المكتوبة ديناميكيًا.

هذا هو السبب في أنني تخليت عن LLVM (وهو أمر مخز ، لأنني أحب ذلك حقًا) ، وأنا أعمل مع RPython. لها إيجابيات وسلبيات:

الايجابيات

  1. RPython مناسب تمامًا: إنه نظام لبناء مترجمين JITted للغات المكتوبة ديناميكيًا. إلى جانب Python (PyPy) ، كتب الناس مترجمين PHP اتضح أنهم أسرع بكثير من اللغة الرسمية ، Ruby ، ​​واللغات المخصصة.

  2. RPython هو نظام رائع لبناء تتبع JITs للغات المكتوبة ديناميكيًا. بالنسبة للغات المكتوبة ديناميكيًا ، يبدو أن تتبع JIT هو الحل الأفضل. يعد تنفيذ JIT للتتبع عملاً شاقًا ويتطلب إضافة نقاط قياس إلى التعليمات البرمجية غير المحجوزة. RPython موجود الآن منذ أكثر من 10 سنوات ، ويعمل عليه أشخاص أذكياء جدًا (وقد تم إصدار عدد قليل من الأوراق الأكاديمية حول RPython) ، ويتطلب منك فعل القليل جدًا للحصول على JIT قيد التشغيل. بشكل أساسي ، يتوقع منك أن تكتب مترجمًا للشفرة الثانوية في RPython وأن تخبره بأي أكواد ثنائية هي تعليمات للقفز ويقوم بالباقي (ويفعل ذلك جيدًا أيضًا ؛ تشير التجارب المبكرة إلى تسريع 40x للحساب الثقيل قد يكون ممكنًا)

  3. كود JITted سريع للغاية ، وهو يدعم واجهات x86 و x64 و ARM الخلفية

  4. إنه مشروع نشط مع عدد غير قليل من الأشخاص الذين يعملون عليه ومجتمع نشط.

  5. مترجم البايت كود والوظائف قابلة للقراءة تمامًا. يبدو التنفيذ الحالي في Variant_op.cpp مروعًا ؛ لا تفهموني بشكل خاطئ ، فأنا أعرف لماذا يبدو الأمر كذلك وأنه ضروري للأداء الجيد ، لكن اختراقه ليس ممتعًا كثيرًا.

السلبيات

  1. (أجزاء من) Variant.cpp تحتاج إلى إعادة كتابتها / تكرارها في RPython.

يجعل حل GDScript للكتابة الديناميكية ، فئة Variant ، من الصعب إنشاء كود JITTed جيد. من الأشياء التي يلاحظها خط أنابيب JIT عندما يتم استدعاء دالة غالبًا بمعامل int ، على سبيل المثال ، ثم تحسينها لهذه الحالة. إذا كنا نستخدم Variant فقط كأنواع مبهمة ، فإن الاختبارات تشير إلى أنه يمكننا فقط تحسين السرعة بمقدار 2x ، لأن كل ما ننتهي إليه بشكل فعال هو ترجمة GDScript إلى كود C ++ الذي يستدعي المتغير بشكل فعال لكل عملية مفردة ، مثل الإضافة أو الاستبدال.

لذلك ، للحصول على الاستخدام الفعلي من JIT ، يجب تكرار بعض أجزاء Variant على الأقل كرمز RPython حتى يعرف JIT ما يحدث. إنها ليست جميلة جدًا ، لكن يبدو أنها تعمل.

  1. ينشئ RPython كود C وليس C ++. Kinda مؤسف ، لكن يمكننا أن نجعلها تعمل ، خاصة مع واجهة GDNative

  2. لدينا كود مكتوب بلغتين ، C ++ و RPython. ومع ذلك ، يستخدم Godot بالفعل SCons ، وهي Python ، لذلك بالمعنى الدقيق للكلمة ، فإننا لا نضيف لغة جديدة

  3. برنامج RPython ليس ممتعًا في البرمجة. ينتهي بك الأمر في الأساس إلى الكتابة بلغة أقوى إلى حد ما من لغة C ، ولكنها ليست قوية مثل C ++ ، ويستغرق الأمر بعض الوقت للتعود على تركيبات Python التي يمكنك استخدامها والتي لا يمكنك استخدامها

  4. تستغرق عملية الترجمة لتحويل كود RPython إلى C (والتي ستكون JIT كاملة العمل) وقتًا طويلاً ، وأنا لا أبالغ. في هذه المرحلة المبكرة من التطوير ، يستغرق الأمر من دقيقة إلى دقيقتين "فقط" ، لكنني أتوقع أن يستغرق التنفيذ الكامل إلى حد ما من 20 إلى 40 دقيقة. هذا ليس فظيعًا كما يبدو ، لأن كود C سيحتاج فقط إلى أن يتم إنشاؤه عندما يتم تعديل JIT نفسه ، وإلا فإن عملية تجميع Godot يمكنها فقط استخدام ملفات C التي تم إنشاؤها.

آمل الحصول على PoC يعمل في غضون 4-8 أسابيع لمزيد من التعليقات.

baekdahl كثرة القراءة. ستتم طباعة GDScript بغض النظر عن رأيك. جاء القرار من القمة وسيحدث في المستقبل القريب.

أصبح CarlGustavAlbertDwarfsteinYung اختياري . فرق كبير لهذه المشكلة.

لجعل قصة طويلة قصيرة: LLVM ليست مناسبة لـ JIT ، لقد قرأت عددًا قليلاً من منشورات المدونة التي وصلت إلى هذا الاستنتاج ، ويبدو أن تجربتي معها تؤكد ذلك أيضًا. هناك سببان رئيسيان:

هذا لأن JIT يجب أن يكون في وقت التطوير. عند إجراء إصدار ، يجب إجراء تجميع أصلي ثابت كامل. LLVM قد لا يكون أسرع JIT، وإنما هو JIT حين التمكن من ترجمة الأصلي تماما مستقل المكتبات / الأجسام / برامج أيضا.

تفترض LLVM أن الكود الخاص بك مكتوب بشكل ثابت ، وهو مناسب تمامًا لتجميع اللغات المكتوبة ديناميكيًا.

ط ط ط ، في الواقع لديها بعض الواجهات الرائعة ديناميكيًا.

بغض النظر ، إذا تمت كتابة GDScript ، فهذه ليست مشكلة على أي حال ، فإن الأجزاء "الديناميكية" من GDScript ستصبح مجرد متغير على أي حال.

هذا هو السبب في أنني تخليت عن LLVM (وهو أمر مخز ، لأنني أحب ذلك حقًا) ، وأنا أعمل مع RPython. لها إيجابيات وسلبيات:

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

يتم كتابتها بشكل اختياري GDScript. فرق كبير لهذه المشكلة.

نعم ، ولكن حتى الأجزاء "غير المصنّفة" هي متغيرات ، وهو أمر تافه إلى حد ما تمثيله في LLVM.

هذا لأن JIT يجب أن يكون في وقت التطوير.

إذن فهو ليس JIT ، ولكنه تجميع طبيعي في وقت مبكر.

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

لا ، إنها JIT. وإذا كان نظام iOS لا يسمح باستخدام JITs ، فلن يعمل هناك. 🤷

نعم ، ولكن حتى الأجزاء "غير المصنّفة" هي متغيرات ، وهو أمر تافه إلى حد ما تمثيله في LLVM.

لكنك لا تحصل على هذا القدر من تحسين السرعة للخروج منه ، كما ذكرت.

من السهل جدًا تجميع GDScript مثل هذا:

while i<10:
    foo(i)
    i = i + 1

إلى ما يعادل C ++ التالية

// i, foo are Variant
while (i.op("<", Variant_10_const)) {
    foo.call(i);
    i = i.op("+", i, Variant_1_const);
}

(أو شيء من هذا القبيل ، لا تتذكر واجهة برمجة تطبيقات Variant بالضبط ، لقد مر بعض الوقت)

ولكن هذا سيجعلك تتحسن السرعة مرتين فقط. من الأصعب بكثير تحويلها إلى while (i<10) {foo.call(new Variant(i)));i += 1} .

ط ط ط ، في الواقع لديها بعض الواجهات الرائعة ديناميكيًا.

أحب أن أسمع عن هؤلاء.

إذن فهو ليس JIT ، ولكنه تجميع طبيعي في وقت مبكر.

قد لا ينتج JIT من الكود سريعًا بشكل عام مثل AOT ، ولكنه وقت دوران أسرع أثناء التطوير ، لذا فهو لا يزال مفيدًا هناك. ومع ذلك ، سأكون جيدًا مع AOT حتى في وقت التطوير لأنه إذا تم تجميع الوحدات الفردية بشكل منفصل ، فلن تكون مشكلة في السرعة بغض النظر (<1s سهلة).

لا ، إنها JIT. وإذا كان نظام iOS لا يسمح باستخدام JITs ، فلن يعمل هناك.

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

لكنك لا تحصل على هذا القدر من تحسين السرعة للخروج منه ، كما ذكرت.

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

(أو شيء من هذا القبيل ، لا تتذكر واجهة برمجة تطبيقات Variant بالضبط ، لقد مر بعض الوقت)

آه ، هذا ليس حتى عن بعد كيف أقترح القيام بذلك بصدق. سيكون إجراء عملية أصلية < عبر زائر أكثر أداءً من اختبار السلسلة كمثال واحد فقط. ومع ذلك ، لست متأكدًا من أن هذا المثال صالح جدًا لأنني أتخيل أن نوع i سيتم استنتاجه كعدد صحيح أعلى حيث تم تعيينه (رمز غير ظاهر) وحتى إذا لم يكن كذلك ، فيمكن أن يكون هناك أن يكون فحصًا من نوع واحد قبل الحلقة للتحقق مما إذا كان يعمل مع مثل هذه المقارنات المتكاملة وإذا لم يطرح استثناءً أو خطأً بطريقة أخرى ، أو احصل على القيمة المتكاملة / الطافية من المتغير (من المحتمل أن يتم تحويله إلى شيء مفيد لتقليل تكوين الكود ، فإن LLVM لديها بالفعل تمريرات لتحسين هذا على الرغم من ذلك) وستصبح الحلقة عندئذٍ غير محسَّنة تمامًا. تريد تقليل الوقت المتغير تمامًا وإجراء عمليات فحص للوصول إليه مبكرًا وفي كثير من الأحيان. التراجع إلى الزائرين ليس بطيئًا إلى هذا الحد ، خاصة وأن غالبية الزائرين قد يخطئون فقط (مثل استدعاء طريقة على عدد صحيح).

ولكن هذا سيجعلك تتحسن السرعة مرتين فقط. إن تحويلها إلى while (i<10) {foo.call(new Variant(i)));i += 1} أكثر صعوبة في تحقيقه.

يبدو أن هذا يمكن تحسينه بشكل تافه؟ سيكون كل شيء أصليًا تمامًا وصولاً إلى استدعاء الترامبولين مقابل foo للإرسال بشكل مناسب أو نحو ذلك (وظيفة غلاف بسيطة لأداء غير مكتوب لكتابة الإرسال أو الخطأ) ، ولكن حتى إذا كان النوع من foo معروف (ممكن أيضًا غير قابل للاستدلال إذا لم يتم كتابته بشكل صريح) ، فسيتم تحسين ذلك أيضًا.

أحب أن أسمع عن هؤلاء.

بخلاف JIT المضمنة لإنشاء التعليمات البرمجية الأصلية التي تمتلكها LLVM نفسها (والتي ستعمل بشكل مثالي مع كل ما سبق وستكون رائعة بالنسبة لوقت التطوير - رمز التحرير أثناء التشغيل بينما لا تزال قادرًا على القيام بـ AOT للإصدارات) الذي يسمح بإجراء مباشر ترجمة JIT ، هناك أيضًا مكتبات مثل pyston و fastlua وغيرها من المكتبات المبنية على LLVM التي تحتوي على أشكال مختلفة من تتبع JIT للتحسين عند الطلب ، والتي أجدها شخصيًا غير مجدية إلى حد ما لوقت التطوير ولا يمكنك استخدامها في إصدار موثوق الوقت على أي حال بسبب منصات مثل iOS ، لذلك لا أرى الهدف.

@ OvermindDL1 ما زلت تتحدث عن AOT الذي يتم تشغيله تلقائيًا عند حفظ GDScript محرر.

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

وإذا أراد الناس تنفيذ شيء من هذا القبيل ، فيمكنهم ذلك. لقد كتبت بالفعل بعض المجمعات الثابتة وهذه المشكلة ليست مثيرة للاهتمام بالنسبة لي.

ما يثير اهتمامي هو إنشاء JIT لـ GDScript مكتوب ديناميكيًا يعمل على أجهزة الكمبيوتر. سيكون من الجيد أن ينتهي الأمر بالآخرين باستخدامه أيضًا ، لكنه ليس شرطًا بالنسبة لي. أنا أقدر التحذير "ربما تضيع وقتك".

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

IIRC ، إنها ليست "<" حقًا ولكنها أكثر من معلمة Operation.LT المعطاة.

يبدو أن هذا يمكن تحسينه بشكل تافه؟

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

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

  • هناك متغير i ، تتم مقارنته ("أقل من") بمتغير آخر تكون محتوياته غير شفافة (على الرغم من أنه يمكنك استخدام واجهة برمجة التطبيقات الداخلية لترى أنه عدد صحيح بقيمة 10)
  • هناك متغير آخر "foo" ، والذي يتم استدعاؤه باستخدام i كمعامل
  • يتم تعيين قيمة جديدة لي ، نتيجة إضافة i إلى متغير معتم آخر

إذا كنت تريد أن تكون قادرًا على القيام بتجميع AOT ، فعليك بشكل أساسي إعادة تطبيق مترجم GDScript بالكامل. وهذا ليس تافهًا كما يبدو ، حيث أن جزءًا مهمًا من المترجم الفوري هو جزء من فئة Variant. و Variant هو ما يجمع godot معًا ، حتى الأجزاء التي ليست GDScript تعتمد بشكل كبير على Variant. لذلك عندما تبدأ في العبث به ، فإنك تخاطر فجأة بكسر التوافق العكسي لواجهة GDNative.

ليس الأمر سهلاً كما يبدو في البداية ؛ لقد فوجئت أيضًا عندما غصت فيها لأول مرة.

ما زلت تتحدث عن AOT الذي يتم تشغيله تلقائيًا عند حفظ GDScript تم تحريره.

ليس في كل مكان ، بل على التصدير فقط. الآن أفضل ما إذا كان AOT عند الحفظ ولكن لا يجب أن يكون كذلك ، يمكنك فقط AOT عند الإصدار / التصدير و JIT عند تشغيله عبر المحرر أو نحو ذلك للسماح بالتبديل السريع للكود أثناء وقت التشغيل.

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

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

ما يثير اهتمامي هو إنشاء JIT لـ GDScript مكتوب ديناميكيًا يعمل على أجهزة الكمبيوتر. سيكون من الجيد أن ينتهي الأمر بالآخرين باستخدامه أيضًا ، لكنه ليس شرطًا بالنسبة لي. أنا أقدر التحذير "ربما تضيع وقتك".

نعم ، يجب ألا يكون JIT إلزاميًا تمامًا لأن هذا يعني أنه لن يكون قابلاً للتصدير إلى جميع الأنظمة الأساسية المدعومة (بالإضافة إلى إضافة النفقات العامة). يجب أن تكون AOT أو الترجمة الفورية هي الطريقة الأساسية دائمًا ، مع الأخذ في الاعتبار أن معظم الأنظمة الأساسية التي لا تدعم JIT (iOS ، webassembly ، إلخ ...) تميل أيضًا إلى أن تكون الأنظمة الأساسية الأقل كفاءة ، لذا يجب أن تكون AOT هي الافتراضية تمامًا ، وليس التفسير ، وهو أفضل منذ إضافة الكتابة.

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

أنا لا أتحدث عن التفسير ، أنا أتحدث عنه من أجل التجميع. إذا تم تجميع رمز غير قابل للطباعة تمامًا ، فسيصبح مجرد متغيرات في رمز الجهاز (نوع المجموع الموسوم) ، وأي وصول إليه ، على سبيل المثال ، لنفترض أن وظيفة operator< ستؤدي فقط استدعاء vistor على ذلك ، والذي يتضمن واحدًا قفزة ثابتة بناءً على قيمة النوع الديناميكي ، ثم تنفيذ الكود الثابت (والذي إذا كان ، على سبيل المثال ، عددًا صحيحًا مضمّنًا ، إذا كان ، على سبيل المثال ، نوعًا مخصصًا ، فمن المحتمل أن ينتهي به الأمر بإجراء مكالمة افتراضية ، أو حتى استدعاء ثابت إذا كان نوعًا كبيرًا يتم تنفيذه مباشرةً في المتغير مثل المتجه).

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

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

هناك متغير i ، تتم مقارنته ("أقل من") بمتغير آخر تكون محتوياته غير شفافة (على الرغم من أنه يمكنك استخدام واجهة برمجة التطبيقات الداخلية لترى أنه عدد صحيح بقيمة 10)

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

هناك متغير آخر "foo" ، والذي يتم استدعاؤه باستخدام i كمعامل

إذا كان نوع المكالمة foo معروفًا ، كمثال في ترميز ML ، int -> int ، إذا كان نوع i معروفًا أيضًا وهو أيضًا int ، فاحرص على الأداء الفعال رمز الجهاز ، إذا كان نوع i غير معروف ، فقم باختبار علامة النوع إذا كانت متطابقة ، وإذا لم تكن متطابقة ، فإن الخطأ ، إذا كان الأمر كذلك ، فاستخرج القيمة وقم بتنفيذ رمز الآلة بكفاءة. إذا كان نوع المكالمة foo غير معروف ولكن علامة النوع تشير إلى أنه قابل للاستدعاء (خطأ آخر) ، فعندئذٍ إذا كان نوع i معروفًا (لجميع تعريفات known أعني هنا كلاهما معروفين في وقت الترجمة وبالتالي غير معبأ) ثم لفه في متغير (إعداد مضمّن فعال لعلامة النوع المناسب ووضع بتات i في البتات المناسبة) وقم بإجراء مكالمة متغيرة إلى وظيفة الترامبولين المغلفة ، والتي تتحقق بعد ذلك من الوسائط وتستدعي الوظيفة الداخلية الفعلية (التي كان يمكن استدعاؤها مباشرة إذا كان نوع استدعاء foo معروفًا بشكل ثابت).

يتم تعيين قيمة جديدة لي ، نتيجة إضافة i إلى متغير معتم آخر

يعتمد الكل على النوع الثابت المعروف i الآن ، وتنفيذ إنشاء الكود الأصلي المناسب الموصوف أعلاه حسب الضرورة.

إذا كنت تريد أن تكون قادرًا على القيام بتجميع AOT ، فعليك بشكل أساسي إعادة تطبيق مترجم GDScript بالكامل.

وهو ما لا يزال أقل عملاً من إنشاء JIT خصيصًا لـ GDScript إلا إذا كنت تقوم بتغليف JIT موجود (والذي قد لا تتطابق عملياته المتوقعة مع GDScript تمامًا). إنشاء AOT بحد ذاته ليس أكثر صعوبة من إنشاء مترجم ، خاصة على LLVM لأنه يقوم بالعمل الشاق بشكل كبير من أجلك (التحسينات ، LTO ، إنشاء كود الآلة ، مصحح الأخطاء ، إلخ ... إلخ ...).

وهذا ليس تافهًا كما يبدو ، حيث أن جزءًا مهمًا من المترجم الفوري هو جزء من فئة Variant.

ولكن لا يزال ليس بالصعوبة التي توحي بها (لقد كتبت مجموعة متنوعة جدًا من اللغات على مر العقود ، والعديد منها يرجع إلى كود الآلة ، مباشرة إلى x86 وعبر LLVM).

و Variant هو ما يجمع godot معًا ، حتى الأجزاء التي ليست GDScript تعتمد بشكل كبير على Variant. لذلك عندما تبدأ في العبث به ، فإنك تخاطر فجأة بكسر التوافق العكسي لواجهة GDNative.

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

ليس الأمر سهلاً كما يبدو في البداية ؛ لقد فوجئت أيضًا عندما غصت فيها لأول مرة.

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

راجع للشغل ، يتم التعامل مع جميع العوامل المتغيرة هنا: https://github.com/godotengine/godot/blob/d2b75557a5dedf951ee036ca01af4f94bc059069/core/variant_op.cpp#L391 -L392

وهو الأمثل بالفعل.

راجع للشغل ، يتم التعامل مع جميع العوامل المتغيرة هنا:

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

لكنك لا تحصل على هذا القدر من تحسين السرعة للخروج منه ، كما ذكرت.

من السهل جدًا تجميع GDScript مثل هذا:

بينما أنا <10:
فو (أنا)
أنا = أنا + 1

إلى ما يعادل C ++ التالية

// i، foo are Variant
while (i.op ("<"، Variant_10_const)) {
foo.call (i) ؛
i = i.op ("+"، i، Variant_1_const) ؛
}

(أو شيء من هذا القبيل ، لا تتذكر واجهة برمجة تطبيقات Variant بالضبط ، لقد مر بعض الوقت)

ولكن هذا سيجعلك تتحسن السرعة مرتين فقط.

ألا تجعله بالفعل GDScript المترجم أسرع من C # في معظم الحالات؟
يبدو الأداء الأفضل بلغة أبسط صفقة جيدة بالنسبة لي.

ألا تجعله بالفعل GDScript المترجم أسرع من C # في معظم الحالات؟

على الأرجح لا ، نظرًا لأنه سيتعين عليه المرور عبر الطبقة المتغيرة بأكملها من المراوغة. بالنظر إلى لغات مثل Wren ، يبدو أن استخدام علامات NaN أو الأنواع غير المعبأة يضر بالأداء أكثر من تجميع الأشياء في كود الآلة. يحتوي C # على كلا النوعين بدون علبة _ و_ تجميع JIT ، لذا فإن تجميع GDScript إلى رمز الجهاز لن يجعله أسرع من C # بطريقة سحرية.
لاحظ أن GDScript يحتوي بالفعل على مُرسل رمز ثنائي مُحسَّن إلى حد كبير ، وأن وجود كود آلة للقيام بالشيء نفسه لن يؤدي إلى تسريع عنق الزجاجة.

حسنًا ، ربما يكون الحل الجيد هو ما يولد رمز c ++ غير المحسن من gdscript (ربما ملف sconscript أيضًا) ثم يقوم المستخدم بالتحسين (لا ينبغي أن يكون الأمر كبيرًا لأن المستخدم كتب النص الأصلي) ويجمعها يدويا.

إنه ليس مثاليًا ولكنه أسرع بالفعل من القيام بكل شيء يدويًا.

إذا كنت ستكتب الرمز مرتين ، فلماذا لا تكتبه في C ++ مباشرة؟

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

يذكرني هذا العدد بلغة Boo . لغة مستوحاة من Python تعمل على .NET.

لا أعرف ما يستحق (لم أستخدمه حقًا tbh) ، ويبدو المشروع ميتًا (5 سنوات؟ لعنة ...) لكنني أرميها على أي حال.

أنا أفضل إعلان نوع Kotlin. إنه أكثر قابلية للقراءة

var name:String = "Bob"

Logmytech لقد

لدى روبي مترجم JIT جديد: https://bugs.ruby-lang.org/projects/ruby/wiki/MJIT#MJIT -organization

مجرد فضول ، هل هذا مخطط لـ 4.0؟

girng ، هناك شك في أن هذا لن يحدث في Godot 4.0. لكنها ليست بالضبط :)

أعتقد أن الإصدار 4.0 يمكن أن يحتوي على تحويل GDScript-to-C الأولي ، تمامًا مثل الإصدار 3.0 الذي يحتوي على دعم C # الأولي.
(إذا كنا محظوظين بما فيه الكفاية).

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

لن يكون لدى Godot 4.0 على الأرجح JIT ، لكن سيكون له تحسينات في الأداء في GDScript.

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

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

أنا أعمل على مفترق يتضمن عددًا من التحسينات التي لا تتطلب تغييرات كبيرة في GDScript على الإطلاق ، ولكنها تحقق بالفعل بعض مكاسب الأداء.

لقد نفذت حتى الآن هياكل البيانات المعيارية لأداء تحسين الكود ، بالإضافة إلى بعض ممرات التحسين الأساسية:

  • بناء وتدمير الرسم البياني للتحكم في التدفق
  • تحليل تدفق البيانات بما في ذلك مجموعات القتل والعشائر والنطاقات الحية
  • القضاء على رمز ميت
  • القفز الترابط (تحسين مهم) لأن GDScript ينشئ الكثير من التفريع غير الضروري

بصفتي POC I أخطط لتنفيذ بضع تمريرات أخرى قبل دفع الشوكة لأعلى:

  • القضاء على التعابير الشائعة
  • اكتب الاستدلال على المؤقتات والحساب الأصلي للمؤقتات (أنا أيضًا لست مقتنعًا بأن الحساب المكتوب سيكون فوزًا كبيرًا)

تتطلب العمليات الحسابية المكتوبة تعديلات على وظائف GDScriptFunction وفئات الحالة الوظيفية لتشمل مصفوفات من السجلات المكتوبة ، بالإضافة إلى أكواد التشغيل الجديدة لمعالجة السجلات المكتوبة وتجنب فحص النوع الإضافي في وقت التشغيل.

يمكنك أن ترى تقدمي في التحسينات المذكورة أعلاه في شوكة godot الخاصة بي ، https://github.com/pchasco/godot/tree/gdscript-optimization/modules/gdscript/optimizer

pchasco قد ترغب في التحدث إلى vnen ، الذي يقوم حاليًا بإعادة صياغة GDScript لـ Godot 4.0 - IMO ، سيكون هذا هو الوقت المناسب للتأكد من الحصول على مثل هذه الفاكهة المتدلية في :)

انظر https://godotengine.org/article/gdscript-progress-report-writing-tokenizer

pchasco قد ترغب في التحدث إلى vnen ، الذي يقوم حاليًا بإعادة صياغة GDScript لـ Godot 4.0 - IMO ، سيكون هذا هو الوقت المناسب للتأكد من الحصول على مثل هذه الفاكهة المتدلية في :)

انظر https://godotengine.org/article/gdscript-progress-report-writing-tokenizer

http://blog.moblcade.com/؟p=114

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

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

vnen نعم ، لم يعد عنوان المشكلة مناسبًا بعد الآن ، إذا قرأت ما ورد أعلاه ، وجدوا أن JIT لا تستحق العناء في الغالب وبدلاً من ذلك ذهبوا إلى التحسينات المستهدفة في المترجم الحالي.

قد يكون من المفيد أن تضع ذلك في اعتبارك أثناء إعادة صياغة ذلك ، ولكن نعم ، ستعرف طريقة أفضل مني عندما يحين الوقت المناسب لمعرفة هؤلاء :) أردت فقط توصيلكما معًا

http://blog.moblcade.com/؟p=114

pchasco قد ترغب في التحدث إلى vnen ، الذي يقوم حاليًا بإعادة صياغة GDScript لـ Godot 4.0 - IMO ، سيكون هذا هو الوقت المناسب للتأكد من الحصول على مثل هذه الفاكهة المتدلية في :)
انظر https://godotengine.org/article/gdscript-progress-report-writing-tokenizer

http://blog.moblcade.com/؟p=114

أرى أنك وجدت مدونتي!

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

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

أوافق على أن JIT ليس حلاً عمليًا نظرًا لعدد الأنظمة الأساسية والأجهزة المختلفة وكمية العمل اللازمة للصيانة. AOT هو بالتأكيد الحل الأبسط والأكثر قابلية للنقل للأداء الأصلي مع GDScript. في الحقيقة Unity transpiles .NET إلى C ++ من أجل AOT أيضًا. سأكون مهتمًا بالمساهمة في إعادة كتابة GDScript.

pchasco أقترح الانضمام إلى قناة IRC # godotengine-devel والتواصل هناك :)

كما ذكرت من قبل ، من غير المرجح أن نضيف JIT. هناك بعض الأفكار الأخرى في المناقشة ولكن لا يوجد استنتاج.

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

بعض المساهمين لديهم أفكار مختلفة لتجميع AOT ، لكنني سأسمح لهم بفتح اقتراح مع وضع ما في ذهنهم.

تضمين التغريدة
ثم يرجى تحديث خارطة الطريق ، إنها تضلل الناس.

حسنًا ، لقد نسيت أن خريطة الطريق موجودة ، ولم يتم تحديثها منذ وقت طويل.

تضمين التغريدة
لقد نسيت ، لكن المستخدمين الآخرين لم يفعلوا ذلك. لذا يرجى تحديثه ، لأن الكثيرين يضعونه في الاعتبار.

المترجمون الفوريون هم هراء وبالنسبة لي هذا يقتل فائدة النص gd عندما يكون الأداء سيئًا

تستخدم مترجمًا عند كتابة محاكي أساسي ، وليس محرك ألعاب كامل

غالبًا ما يكون المترجم في الوقت المناسب أسرع من مترجم الحمار البطيء الذي عفا عليه الزمن على أي حال ، ونظام المترجم الفوري هو مجرد سيء بسيط وبسيط ، وأشعر أنني أفضل حذف نص gd والانتقال فقط إلى ++ C ، وإنشاء إعداد الحي اليهودي مع نظام في الوقت المناسب

أعتقد أن الناس ليسوا على استعداد للاعتراف بأن المترجم هراء لأن الناس لا يريدون إيذاء مشاعر بعضهم البعض لسبب ما ، ولكن بالمقارنة مع c ++ ، فإن النتيجة النهائية جميلة ، إيه ...

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

@ RaTcHeT302 لا داعي لإحضار السلبية الخاصة بك وتذكر أن لدينا مدونة لقواعد السلوك . هناك خطط لتحسين GDScript بعدة طرق ، بما في ذلك التحويل البرمجي إلى التعليمات البرمجية الأصلية ، وليس فقط باستخدام JIT. أيضًا إذا قارنت مع C ++ ، فسيكون وقت تشغيل JITed بطيئًا.

vnen : فقط قل أن LuaJIT قريب من وجود C / C ++ في معايير الأداء - ولكن هناك اعتقاد شائع بأن السحر متضمن: ابتسم:

JIT غير ممكن على جميع المنصات الرئيسية. من الأفضل تركيز الجهود
حيث يمكن للجميع الاستفادة منها. قبل تجميع الوقت هو الوحيد
تكنولوجيا متوافقة 100٪.

في الأحد 9 أغسطس 2020 الساعة 8:46 صباحًا كتب Zireael07 [email protected] :

vnen https://github.com/vnen : فقط قل أن LuaJIT على وشك الانتهاء
هناك مع C / C ++ على معايير الأداء - ولكن هناك على نطاق واسع
الاعتقاد بأن السحر متورط 😄

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-671047838 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAUFIAGK3S7RA3DRXW6NUC3R72LCVANCNFSM4CFZMZPA
.

ألا توجد سلبيات لـ AoT مقارنة بـ JIT؟ على سبيل المثال ، ماذا عن البرامج النصية التي يتم إنشاؤها أو تحميلها ديناميكيًا؟ لا ينبغي أن يكون لدى JIT مشكلة في تحسينها ، ولكن AoT؟

بالمناسبة ، على أي منصة رئيسية لا يمكن JIT؟ اعتقدت أن Java مع JIT الخاص بها يعمل إلى حد كبير في كل مكان.

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

لا يسمح iOS لـ JIT للتطبيقات الموزعة من خلال App Store
ما لم تكن تستخدم مكون متصفح Apple.

لن يكون AOT ممكنًا للنصوص الديناميكية.

في الأحد 9 أغسطس 2020 الساعة 11:15 صباحًا كتب monnef [email protected] :

ألا توجد سلبيات لـ AoT مقارنة بـ JIT؟ على سبيل المثال ماذا عن
إنشاء أو تحميل البرامج النصية ديناميكيًا؟ لا ينبغي أن يكون لدى JIT مشكلة
تحسينها ، ولكن AoT؟

بالمناسبة ، على أي منصة رئيسية لا يمكن JIT؟ اعتقدت جافا
مع JIT الخاص به يعمل إلى حد كبير في كل مكان.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-671064117 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAUFIACWWCWDXO4NZ7GCL63R724RHANCNFSM4CFZMZPA
.

لا تدعم أنظمة التشغيل iOS والويب وبعض الأنظمة الأساسية لوحدة التحكم تجميع JIT.

هناك شائعة تفيد بأن AOT قد تم إلقاؤها الآن من على سطح السفينة مع JIT. آمل أن هذا ليس صحيحًا. شخص ما ، من فضلك قل لي ، هل هذا صحيح؟

هل تقول أن هناك شائعة AOT لم يعد مسموحًا بها على البعض
الأجهزة؟ هذا مستحيل حرفيًا ، ما لم أسيء فهم شيء ما؟

يوم الأربعاء 30 سبتمبر 2020 الساعة 5:47 صباحًا كتب Teashrock [email protected] :

>
>

Calinou https://github.com/Calinou neikeq https://github.com/neikeq
reduz https://github.com/reduz @ akien -mga
https://github.com/akien-mga

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-701313134 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAUFIADVHAXMGBOL3YEDVILSIMEEFANCNFSM4CFZMZPA
.

تضمين التغريدة
لا ، أعني ، أخبرني أحدهم أن GDScript لن تمتلك AOT ولا JIT.

ربما لن يتم دعمه رسميًا ، لكن يمكنني أن أؤكد أن الجديد
بنية GDScript المحددة بواسطة vnen قادرة على دعمها. ان
يمكن للمطور المغامر تنفيذ وحدة مخصصة للقيام بـ AOT
GDNative C.

يوم الأربعاء 30 سبتمبر 2020 الساعة 11:16 صباحًا كتب Teashrock [email protected] :

>
>

pchasco https://github.com/pchasco

لا ، أعني ، أخبرني أحدهم أن GDScript لن تمتلك AOT ولا JIT.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-701494412 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAUFIACAKZVJQK2CHTDJT63SINKXDANCNFSM4CFZMZPA
.

تضمين التغريدة

يمكن

لذا ، أنت لا تعرف. "قادر على الدعم" لا يعني "سوف يدعم".

Teashrock لا نعرف ما إذا كان GDScript سيعرض تجميع JIT أو AOT في 4.0 ، لكن هذا غير محتمل جدًا. ربما في 4.1 أو أحدث ...

إذا كنت بحاجة إلى أداء أعلى لأغراض معالجة الأرقام (أي أن قيود وحدة المعالجة المركزية تأتي بوضوح من لغة البرمجة النصية) ، فاستخدم C #. لكن أولاً ، اقرأ دروس التحسين :

تضمين التغريدة
لقد تحدثوا فقط عن 4.0 بخصوص JIT / AOT. والآن أنت تقول لي عن 4.1. لماذا هذا؟ كيف ذلك؟ شخص ما ، فقط أعط الجميع إجابة عامة واضحة ، والتي لن تكون في مكان ما عميق على GitHub.

شكرا لكم مقدما.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات