كيفية الحصول على وقت تنفيذ البرنامج النصي

مساحة Kernel مقابل مساحة المستخدم
CS العمارة

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

كانت إحدى المشكلات التي واجهتها هي أن وقت تنفيذ البرنامج النصي زاد بشكل ملحوظ من الثانية إلى 17.58 ثانية. تمكنت من تحديد وقت تنفيذ كل سطر على البرنامج النصي وعزله. جئت أدركت أن الأمر raspistill استغرق 5. 87 ثانية لتنفيذه. مما يؤدي إلى فقدان تماما لالتقاط صورة للشخص الذي يفتح الباب.

كيفية تقليل وقت تنفيذ raspistill

تعليمة raspistill بسيطة تتبعها علامة "- help" على الجهاز توفر مزيدًا من المعلومات حول أوامر معلمة الصورة:

بي @ raspberrypi: ~ $ raspistill - مساعدة
يقوم بتشغيل الكاميرا لفترة محددة ، والتقاط JPG في النهاية عند الطلب
الاستخدام: raspistill [خيارات]
أوامر معلمة الصورة
...
-t ، - المهلة: الوقت (بالمللي ثانية) قبل التقاط الصورة وإيقافها (إن لم يكن محددًا ، اضبط على 5 ثوانٍ)

تمكنت من تقليل وقت تنفيذ raspistill إلى بضع ميلي ثانية بتحديد الوقت قبل التقاط الصورة في البرنامج النصي على النحو التالي:

كيفية الحصول على وقت تنفيذ البرنامج النصي بشكل فعال

خلال هذه العملية ، أتعرف على أمر الوقت ، والذي يُستخدم للحصول على الوقت الذي يستغرقه تنفيذ أمر أو نص برمجي آخر:

وقت yourscript.sh / / الحصول على تنفيذ لبرنامج نصي
time ls // get وقت تنفيذ الأمر ls

والتي أعطت النتيجة التالية:

لقطة شاشة محطة لأمر

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

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

سيخبرك User + Sys بوقت وحدة المعالجة المركزية الفعلي الذي استخدمته. لاحظ أن هذا عبر جميع وحدات المعالجة المركزية ، لذلك إذا كانت العملية بها عدة مؤشرات ترابط (وكانت هذه العملية قيد التشغيل على جهاز كمبيوتر به أكثر من معالج) ، فمن المحتمل أن تتجاوز وقت ساعة الحائط التي أبلغ عنها Real (والتي تحدث عادة). لاحظ أنه في المخرجات ، تتضمن هذه الأرقام وقت المستخدم ونظام Sys لجميع العمليات الفرعية (وأحفادهم) وكذلك عندما يمكن جمعها ، على سبيل المثال عن طريق الانتظار (2) أو waitpid (2) ، على الرغم من أن استدعاءات النظام الأساسي تقوم بإرجاع إحصائيات العملية وأطفالها بشكل منفصل.

أصول الإحصاءات المبلغ عنها حسب الوقت (1)

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

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

مقدمة موجزة عن Kernel مقابل وضع المستخدم

في نظام التشغيل Unix أو أي نظام تشغيل للذاكرة المحمية ، يشير وضع "Kernel" أو "Supervisor" إلى وضع متميز يمكن لوحدة المعالجة المركزية تشغيله. لا يمكن القيام ببعض الإجراءات المميزة التي يمكن أن تؤثر على الأمان أو الاستقرار إلا عندما تعمل وحدة المعالجة المركزية في هذا الوضع. هذه الإجراءات غير متاحة لرمز التطبيق.

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

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

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

تحتوي مكالمات "النظام" في مكتبة C (خاصة تلك الموضحة في القسم 2 من صفحات الدليل) على مكون وضع المستخدم ، وهو ما تسمونه فعليًا من برنامج C. خلف الكواليس ، قد يصدرون مكالمة نظام أو أكثر إلى kernel للقيام بخدمات معينة مثل I / O ، ولكن لا يزال لديهم أيضًا رمز يعمل في وضع المستخدم.

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

المزيد عن "sys"

هناك أشياء لا يمكن أن يقوم بها الكود الخاص بك من وضع المستخدم - أشياء مثل تخصيص الذاكرة أو الوصول إلى الأجهزة (HDD ، الشبكة ، إلخ). هذه هي تحت إشراف النواة ، وأنها وحدها يمكن أن تفعل ذلك. بعض العمليات التي تقوم بها (مثل malloc orfread / fwrite) سوف تستدعي وظائف Kernel والتي ستحسب كوقت "sys". لسوء الحظ ، ليس الأمر بسيطًا مثل "سيتم احتساب كل مكالمة إلى malloc في وقت" sys ".

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

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

بعض محتويات هذه المقالة هي مزيج من الإجابات المنشورة في البداية على Stack Overflow
إذا كنت قد استمتعت بهذا المقال ، فقد ترغب أيضًا في "كيفية إنشاء تطبيق ثنائي الاتجاه لـ Internet of Things / Chat مع Python"
يرجى إعطائها بعض التصفيق للحصول على الدعم!
في صحتك!!!