System Image Building
Building the Julia system image
تأتي جوليا مع صورة نظام مُعَدَّة مسبقًا تحتوي على محتويات وحدة Base
، تُسمى sys.ji
. يتم أيضًا تجميع هذا الملف مسبقًا في مكتبة مشتركة تُسمى sys.{so,dll,dylib}
على أكبر عدد ممكن من المنصات، وذلك لتحسين أوقات بدء التشغيل بشكل كبير. على الأنظمة التي لا تأتي مع ملف صورة نظام مُعَدَّة مسبقًا، يمكن إنشاء واحدة من ملفات المصدر المرسلة في مجلد DATAROOTDIR/julia/base
الخاص بجوليا.
ستقوم جوليا بشكل افتراضي بإنشاء صورة النظام الخاصة بها على نصف خيوط النظام المتاحة. يمكن التحكم في ذلك بواسطة متغير البيئة JULIA_IMAGE_THREADS
.
هذه العملية مفيدة لعدة أسباب. يمكن للمستخدم أن:
- قم ببناء صورة نظام مكتبة مشتركة مسبقة التجميع على منصة لم تُشحن بها، مما يحسن أوقات بدء التشغيل.
- قم بتعديل
Base
، وأعد بناء صورة النظام، واستخدمBase
الجديدة في المرة القادمة التي يتم فيها بدء تشغيل جوليا. - قم بتضمين ملف
userimg.jl
الذي يتضمن الحزم في صورة النظام، مما يؤدي إلى إنشاء صورة نظام تحتوي على الحزم المدمجة في بيئة بدء التشغيل.
تحتوي PackageCompiler.jl
package على دوال تغليف مريحة لأتمتة هذه العملية.
System image optimized for multiple microarchitectures
يمكن تجميع صورة النظام في وقت واحد لعدة معمارية ميكروية لوحدة المعالجة المركزية تحت نفس بنية مجموعة التعليمات (ISA). يمكن إنشاء إصدارات متعددة من نفس الوظيفة مع إدخال نقطة توزيع الحد الأدنى في الوظائف المشتركة للاستفادة من امتدادات ISA المختلفة أو ميزات المعمارية الميكروية الأخرى. سيتم اختيار الإصدار الذي يقدم أفضل أداء تلقائيًا في وقت التشغيل بناءً على ميزات وحدة المعالجة المركزية المتاحة.
Specifying multiple system image targets
يمكن تمكين صورة نظام متعددة المعمارية الدقيقة عن طريق تمرير أهداف متعددة أثناء تجميع صورة النظام. يمكن القيام بذلك إما باستخدام خيار JULIA_CPU_TARGET
أو باستخدام خيار سطر الأوامر -C
عند تشغيل أمر التجميع يدويًا. يتم فصل الأهداف المتعددة بواسطة ;
في سلسلة الخيار. التركيب لكل هدف هو اسم وحدة المعالجة المركزية متبوعًا بميزات متعددة مفصولة بـ ,
. جميع الميزات المدعومة من LLVM مدعومة ويمكن تعطيل ميزة باستخدام بادئة -
. (بادئة +
مسموح بها أيضًا ويتم تجاهلها لتكون متسقة مع تركيب LLVM). بالإضافة إلى ذلك، يتم دعم بعض الميزات الخاصة للتحكم في سلوك استنساخ الوظائف.
من الممارسات الجيدة تحديد إما clone_all
أو base(<n>)
لكل هدف باستثناء الهدف الأول. هذا يجعل من الواضح أي الأهداف تم استنساخ جميع الوظائف لها، وأي الأهداف تعتمد على أهداف أخرى. إذا لم يتم ذلك، فإن السلوك الافتراضي هو عدم استنساخ كل وظيفة، واستخدام تعريف وظيفة الهدف الأول كخيار احتياطي عند عدم استنساخ وظيفة.
clone_all
بشكل افتراضي، سيتم استنساخ الوظائف التي من المرجح أن تستفيد من ميزات المعمارية الدقيقة فقط. عندما يتم تحديد
clone_all
كهدف، سيتم استنساخ جميع الوظائف في صورة النظام لهذا الهدف. يمكن استخدام الشكل السلبي-clone_all
لمنع الخوارزمية المدمجة من استنساخ جميع الوظائف.base(<n>)
حيث
<n>
هو عنصر نائب لعدد غير سالب (مثلbase(0)
،base(1)
). بشكل افتراضي، سيستخدم الهدف الذي تم نسخه جزئيًا (أي ليسclone_all
) وظائف من الهدف الافتراضي (الأول المحدد) إذا لم يتم نسخ وظيفة. يمكن تغيير هذا السلوك عن طريق تحديد قاعدة مختلفة باستخدام خيارbase(<n>)
. سيتم استخدام الهدفn
(بدءًا من 0) كهدف أساسي بدلاً من الهدف الافتراضي (0
). يجب أن يكون الهدف الأساسي إما0
أو هدف آخر من نوعclone_all
. سيؤدي تحديد هدف غيرclone_all
كهدف أساسي إلى حدوث خطأ.opt_size
هذا يتسبب في تحسين دالة الهدف من حيث الحجم عندما لا يكون هناك تأثير كبير على أداء وقت التشغيل. هذا يتوافق مع خيار
-Os
في GCC و Clang.min_size
هذا يتسبب في تحسين دالة الهدف من حيث الحجم مما قد يؤثر بشكل كبير على أداء وقت التشغيل. وهذا يتوافق مع خيار Clang
-Oz
.
كمثال، في وقت كتابة هذا، يتم استخدام السلسلة التالية في إنشاء ثنائيات x86_64
الرسمية لجوليا القابلة للتنزيل من julialang.org:
generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)
هذا ينشئ صورة نظام مع ثلاثة أهداف منفصلة؛ واحد لمعالج x86_64
العام، واحد مع ISA sandybridge
(يستبعد بشكل صريح xsaveopt
) الذي ينسخ جميع الوظائف بشكل صريح، وواحد يستهدف ISA haswell
، بناءً على إصدار sysimg sandybridge
، ويستبعد أيضًا rdrnd
. عندما يقوم تنفيذ Julia بتحميل sysimg الذي تم إنشاؤه، سيتحقق من معالج المضيف لعلامات قدرة CPU المتطابقة، مما يمكّن أعلى مستوى ISA ممكن. لاحظ أن المستوى الأساسي (generic
) يتطلب تعليمات cx16
، والتي يتم تعطيلها في بعض برامج المحاكاة ويجب تمكينها لتحميل الهدف generic
. بدلاً من ذلك، يمكن إنشاء sysimg مع الهدف generic,-cx16
من أجل توافق أكبر، ومع ذلك، لاحظ أن هذا قد يسبب مشاكل في الأداء والاستقرار في بعض الشيفرات.
Implementation overview
هذا ملخص موجز للأجزاء المختلفة المعنية في التنفيذ. راجع تعليقات الشيفرة لكل مكون لمزيد من تفاصيل التنفيذ.
تجميع صورة النظام
تتم قرارات التحليل والاستنساخ في
src/processor*
. نحن ندعم حاليًا استنساخ الدوال بناءً على وجود الحلقات، تعليمات SIMD، أو عمليات رياضية أخرى (مثل fastmath، fma، muladd). يتم تمرير هذه المعلومات إلىsrc/llvm-multiversioning.cpp
التي تقوم بالاستنساخ الفعلي. بالإضافة إلى القيام بالاستنساخ وإدراج فتحات التوزيع (انظر التعليقات فيMultiVersioning::runOnModule
حول كيفية القيام بذلك)، يقوم الممر أيضًا بإنشاء بيانات وصفية بحيث يمكن للنظام في وقت التشغيل تحميل وت初始化 صورة النظام بشكل صحيح. تتوفر وصف تفصيلي للبيانات الوصفية فيsrc/processor.h
.تحميل صورة النظام
يتم تحميل وت inicialization صورة النظام في
src/processor*
عن طريق تحليل البيانات الوصفية المحفوظة أثناء توليد صورة النظام. يتم الكشف عن ميزات المضيف وقرار الاختيار فيsrc/processor_*.cpp
اعتمادًا على ISA. ستفضل عملية اختيار الهدف مطابقة اسم وحدة المعالجة المركزية بالضبط، وحجم سجل المتجهات الأكبر، وعدد الميزات الأكبر. نظرة عامة على هذه العملية موجودة فيsrc/processor.cpp
.