الزمن الذاتي والكلي في المحلل يحملان تعريفين مختلفين. في شفرة PyTorch المحددة، يطرح الزمن الذاتي لحدث CPU المتزامن أزمنة أبنائه المباشرين من زمنه الكلي. [1] نقرأ الصيغة ثم نحسب شجرة أوقات مؤلفة.
الخلاصة السريعة
لا تجمع زمن الأب الكلي مع زمن ابنه كجزأين مستقلين؛ جزء الابن داخل الأب في عقدنا. حدد نوع الحدث والعلاقة بينهما قبل جمع الأعمدة.
- الصيغة التي ندرسها تخص حدث CPU متزامنا؛ الزمن الذاتي يطرح مجموع الزمن الكلي للأبناء المباشرين من زمن الأب الكلي. [1]
- لأب مدته 10 وابن مباشر مدته 6 داخلها، زمن الأب الذاتي 4؛ جمع 10 و 6 يكرر مدة الابن، بينما جمع 4 و 6 يعطي 10 في الشجرة المعلنة.
- إذا كان داخل الابن حفيد مدته 2، يبقى الأب الذاتي 4 ويصبح الابن الذاتي 4 والحفيد 2؛ جمع الذاتيات 10، ولا نطرح الحفيد مرة أخرى من الأب.
- يعيد التنفيذ صفرا لحقل self_cpu_time_total لحدث غير CPU أو غير متزامن. [1] لا يعني ذلك غياب عمل الجهاز، ولا يحول جمع أحداث متداخلة بين خيوط إلى زمن طلب كامل.
اقرأ الحقل وشروط الصيغة
في تنفيذ PyTorch 2.14.0، cpu_time_total لحدث CPU هو طول فترته، وself_cpu_time_total يطرح أزمنة الأبناء المباشرين؛ لغير CPU أو غير المتزامن يعيد الحقل الذاتي صفرا. [1]
نحصر الحساب التالي في أحداث CPU متزامنة على خيط واحد، ذات علاقات احتواء معلنة. لا نخلط هذا الحقل بحقل وقت جهاز آخر لمجرد ظهوره بجواره في تقرير، ولا نفترض أن صيغة كل أداة تحليل مطابقة.
وكلمة «ذاتي» هنا جزء حسابي وفق تعريف الحقل. ليست مقدار جهد شخص أو جودة عملية، ولا يلزم أن يساوي زمن استدعاء العميل كاملًا. تعريف الفترة والجهة التي سجلتها يسبق تفسير ترتيب الصفوف.
الأب يتضمن مدة ابنه
نؤلف حدث أب تبدأ فترته عند صفر وتنتهي عند 10، وابنا مباشرا يبدأ عند 2 وينتهي عند 8، دون أحداث أخرى. الأوقات وحدات ورقية على الخط نفسه، وليست ميكروثواني التقطها محلل.
زمن الأب الكلي 10، والابن 6. تحت الصيغة المحددة، الأب الذاتي 10 ناقص 6، أي 4. ولأن الابن بلا أبناء في هذا الفرع، زمنه الذاتي 6. مجموع الذاتيين 4 + 6 = 10.
أما جمع الكليين 10 + 6 فيعطي 16، لكنه ليس طول النافذة من صفر إلى 10. أعدنا عد الفترة من 2 إلى 8. لا نعالج الخطأ بحذف صف الابن من السجل؛ نحفظ الصف ونوضح نوع العدد الذي نجمعه.
ماذا يضيف حفيد داخل الابن؟
نضيف حفيدا من 4 إلى 6 داخل الابن نفسه، ولا نغير حدود الأب أو الابن. مدته 2، وهو ابن مباشر للابن وليس ابنا مباشرا للأب في شجرتنا.
يبقى الأب الذاتي 10 ناقص 6، أي 4. الابن الذاتي يصبح 6 ناقص 2، أي 4؛ والحفيد الذاتي 2 لأنه بلا أبناء. مجموع 4 + 4 + 2 ما زال 10 تحت هذا الاحتواء، رغم إضافة صف في التقرير.
لو طرحنا من الأب 6 ثم 2، عدنا طرح جزء داخل الست مرتين. تقتضي الصيغة هنا الأبناء المباشرين، لا كل صف أسفل الأب. لا نغير العلاقة لأن التقرير فرز العمليات بحسب الاسم أو الزمن وأبعد صف الابن عن أبيه.
متى لا نقرأ الصفر على أنه لا عمل؟
الصفر الذي تعيده الصيغة للحقل الذاتي في الحالات المستثناة لا يثبت أن جهازا لم يعمل. نحن نقرأ شرط حقل معين، ولم نرصد جميع أحداث البرنامج أو أوقاته.
كذلك يختلف جمع مدد أحداث على خيوط متعددة عن نافذة زمنية شاملة؛ قد تتداخل أعمالها. شجرتنا ذات خيط واحد لا تمنح قاعدة تجمع كل أعمدة CPU وGPU لتقرير زمن الطلب أو سبب البطء.
احتفظ بنوع الحدث وعلاقاته المباشرة وتعريف العمود ووحدة القياس. الرسم يصور أبًا وابنًا وحفيدًا بأوقات معلنة. لم نشغل profiler أو نستخرج أثرا؛ الحساب يمنع العد المكرر في الشجرة، دون تشخيص أداء نموذج حقيقي.
المصادر ومتابعة القراءة
- PyTorch2.14.0: profiler_util.py (يفتح في نافذة جديدة)raw.githubusercontent.com
أُعدّ هذا المقال بصياغة عربية أصلية بالاستناد إلى المصادر أعلاه، وهو مدخل تمهيدي إلى الموضوع. اقرأ منهجية المحتوى وحدوده.
