AhmedSalah
السلام عليكم يا شباب. يا رب تكونوا بخير جميعًا. آخر محاضرة إن شاء الله في الـ course، بشكركم طبعًا على الاهتمام وعلى المتابعة طول الـ term يعني، أتمنى يكون الـ course يعني حقق الاستفادة المرجوة يا رب إن شاء الله ونكون استفدنا منه يعني. موضوع النهارده عن الـ scheduling، عن بس على الـ multi-processor، إحنا كنا خدنا قبل الـ midterm الـ scheduling على الـ single processor.
النهارده هنتكلم على إزاي نـ schedule على multi-processors. بعض الـ announcements بس في الأول سريعًا كده، الأسبوع ده هو كان آخر معمل اللي هو المعمل اللي شغال، كان شغال النهارده يعني. المعمل ده فيه explain لـ concept كنا سبناه من المحاضرة.
اللي قبل اللي فاتت اللي هو check and go، فمهم تسمعوا المعمل عشان تعرفوا الـ concept ده أو الـ issue دي وإزاي بنحلها. في يعتبر إن أنت بتاخد فيه مثال زيادة على الـ concurrency، إحنا خدنا هنا في المحاضرة مثالين، في الـ problem sessions حلينا برضه مثالين أو ثلاثة.
فالمعمل هدفه إنه بيديك أمثلة أكتر، سواء من ناحية إزاي تفكر فيها algorithmic-wise، pseudocode يعني، أو كمان إزاي تـ implement ده على الـ C#. فالمعمل مهم يعني أرجو، ممكن أتمنى تكون الناس اللي كانت موجودة النهارده حضارته يعني، واللي ما حضرش هو كده كده.
هيبقى متسجل وهينزل لكم إن شاء الله، فضروري نسمعه لأهميته سواء في يخدم المحاضرة أو بيخدم الشغل العملي بتاعنا. الـ project support إن شاء الله هيبقى خلال بقية الأسبوع في توقيت في أوقات المعامل في بقية الأسبوع.
بس according للـ schedule المفروض إنه أعتقد نزل لكم على Teams يعني. جدول مفصل كده فيه كل معيد موجود في أنهي ميعاد، والمكان اللي هو موجود فيه طبعًا بيبقى هو mainly في مكان المعمل يعني. فده بالنسبة للـ project support، وطبعًا الـ office hours ما بتبقاش مفعلة بقى الأسبوع ده.
باستثناء المحاضر يعني، أنا معادي زي ما هو بكرة. بالنسبة للمعيدين هما بقى بدلوا مواعيد الـ office hours بمواعيد الـ support اللي هي في السكاشن. فأتمنى إن شاء الله نستغل مواعيد الـ support دي علشان هو دي تقريبًا آخر أسبوع هيبقى فيه support.
إن شاء الله. دي بعض المصادر لـ examples بالـ solution بتاعتها متجمعة هنا أهو، سواء بقى للـ sheets اللي كانت خلال الـ term كله اللي كانت ورا المحاضرات. في برضه revision materials دي عليها بعض الـ previous exams.
الـ problem sessions دي videos، وكذلك videos كانت من revisions قبل كده. بفكركم هدف المصادر المختلفة دي إن أنت يبقى عندك مصادر أسئلة موجودة بالحل بتاعها، سواء الحل مشروح أو مكتوب، بحيث إن أنت تـ practice على الحل، بس الأهم من إن أنت تقعد تسمع.
أو تتفرج أو تشوف الحل الأهم إن أنت تحل at your own، وده اللي كان ملاحظ الملاحظة كانت واضحة في الـ midterm. فضروري نحل by yourself، لازم تمسك ورقة وقلم وتفكر تحل، وأنت اللي تحل بنفسك.
سواء بقى ممكن من خلال الـ sheets المسائل اللي ما اتحلتش، من خلال الـ sessions لو أنت بتسمع الـ session ممكن قبل ما تسمع الحل، وقف الـ video وادي لنفسك فرصة تفكر في الحل، شوف تفكيرك هيجيب إيه وبعدين بص على الحل أو تابع الـ video، يعني المهم إن أنت تدي لنفسك فرصة إن أنت تحل. ده ضروري يا شباب في أي حاجة فيها.
practicing أو تفكير أو مسائل يعني. فبنأكد على النقطة دي ضروري وأنتوا بتذاكروا إن شاء الله. طيب summary كده إيه اللي اتعلمناه في الـ course حتى الآن؟ طبعًا ده overall summary كده قلنا إن الـ operating system هو مكانه ما بين الـ hardware باختلاف الـ devices اللي فيه.
وما بين الـ applications، فهو layer في النص اللي بيـ manage الـ applications على الـ hardware. فكرته الأساسية إنه بيـ abstract الـ hardware يعني ما ينفعش الـ applications يبقى ليها direct access على الـ physical content بتاع الـ hardware، فهو دايمًا بيعمل.
فكرة الـ abstraction فمثلًا الـ processors كان بي abstract الـ registers بتاعتها في threads. الـ memory الرامات كان بي abstract في شكل address spaces اللي هي الـ directory والـ page tables والكلام ده. الـ storage والـ disk بي abstract في files و directories.
الـ network sockets وهكذا، فهو بيعمل دايمًا نوع من الـ abstraction، طبعًا دي كلها بتبقى عبارة عن data في الآخر زي ما شفنا يعني. بيجمع الـ data دي كلها في single struct سميناه الـ process أو عندكم في المعمل سميناه environment، فكل برنامج ليه الـ process الخاصة بيه.
اللي فيها جميع بياناته أثناء الـ lifetime بتاعه أو الـ lifecycle بتاعته. الـ compiled programs بقى بالـ libraries بتاعتها بتتعامل مع أخرها تتعامل مع الـ system calls اللي الـ operating system بيديها لها أو إن هي تـ access المحتوى اللي جوه الـ process، لكن ما لهاش إن هي تـ access مباشرةً.
الـ hardware. طيب إحنا بقى تعلمنا إيه في خلال الـ course؟ تعلمنا ثلاثة issues أساسية. الـ competition اللي على الـ memory، اللي هي فكرة الـ address spaces وإزاي بتتعمل وإزاي بنـ manage ده بالتفصيل وبالمشاكل بتاعتها والحلول بتاعتها.
وتعلمنا إزاي نـ schedule على single processor والنهارده بنكمل الـ multi-processor. فبرضه إزاي الـ decisions بتتاخد وتعلمنا إزاي ما يكون عندي كذا برنامج شغالين concurrently، إزاي نـ resolve المشاكل اللي بتحصل نتيجة الـ concurrent execution.
سواء بيبدلوا على single processor أو شغالين parallel على multi-processors. شفنا إن دايمًا هتظهر لنا مشاكل وشوفنا بعض الـ issues وبعض الحلول للمشاكل دي. واتعلمنا حلول المشاكل دي بالـ shared resources، وكمان المشاكل اللي بتنتج عنها اللي هي الـ deadlocks.
وفنا إزاي نتعامل معاها في آخر محاضرة اللي هي الأسبوع اللي فات. ده summary للي اتعلمناه، الـ know-how بتاع الـ OS في ثلاث حاجات دول، الـ memory بشقينها chapter 7 و8، الـ processor single و multi-processors، والـ shared resources كانت ممثلة في إزاي نعمل critical sections.
ونتيجة الـ critical sections تظهر مشكلة الـ deadlock، فشوفنا إزاي نتعامل مع مشكلة الـ deadlock والحلول بتاعتها. فده summary و hope إن هو يلخص تبقى معاكم كده خريطة بالـ course وإيه اللي اتعلمناه. تحت الـ memory تعلمنا طريقتين الـ paging والـ segmentation، تحت الـ virtual memory تعلمنا برضه إزاي نقلب كل واحدة من دول virtual.
تعلمنا مشكلتين بالحل بتاعهم، تعلمنا بعض الـ rules بتاعة الـ OS وبالأخص الـ replacement، الـ scheduling على single processor تعلمنا خمس طرق اللي هما الـ priority-based، واثنين non-preemptive، واثنين preemptive. الـ multi هنتعلمه النهارده إن شاء الله، برضه فيه حوالي ثلاث أو أربع طرق.
الـ critical sections شفنا إزاي نـ implement الـ critical section مرة بالـ hardware بالأخص باستخدام الـ locks باختلاف أنواعها، ومرة باستخدام supporting من الـ OS اللي هو الـ semaphores، وشفنا ركزنا قوي على الـ semaphores إن إحنا نحل بيها concurrency issue، تعلمنا خمسة issues من خلال.
محاضرة كاملة خدناها هنا، المثال بتاع الـ barber shop تعلمنا فيه إزاي نـ resolve خمسة issues، والـ issue السادسة هتاخدوها اللي هو معمل الأسبوع ده إن شاء الله. والـ deadlock finally تعلمنا إيه شروط الـ deadlock، وإزاي نتعامل معاه بواحدة من أربع طرق، يا prevention، avoidance، detection، أو integration ما بينهم كلهم.
ده كان ملخص للـ course كله، أتمنى يكون يا رب حققنا استفادة ولو جزئية لحضراتكم، أتمنى تكونوا استمتعتوا بالـ course يعني إن شاء الله. طبعًا المعمل كان الجزء الأكبر كان مركز على الـ memory، memory management. آخر ثلاث معامل كانوا ركزوا على الـ concurrency، وده بنأكد إن الـ topic ده مهم ليكم بعد كده.
في الشغل بعيدًا عن الـ course، فكرة إن أنت إزاي تكتب concurrent code وتـ resolve الـ issues اللي فيه. أنا ما حدش بره بيكتب single thread دلوقتي، نادر يعني ما هتلاقي حد بيكتب single thread. والـ project سمع في الثلاثة باختلاف في الـ milestones بتاعتهم. اتعلمت تـ implement حاجة من كل حاجة أو أكتر من حاجة من كل حاجة، تعلمنا من الـ shared resources الـ semaphores، milestone.
الـ scheduler بتعمله priority-based. الـ memory خدناها على two milestones، one و two يعني. فأنت لمست في المشروع بتاعك الثلاثة topics، فأتمنى يكون حاجة إن شاء الله نكون الأهم طبعًا استفدنا منها وحاجة نفتخر بيها إن شاء الله في الـ CV بتاعنا. هنتعلم إيه النهارده؟ intro عن الموضوع.
three design issues مهم لازم الـ OS ياخد قرار فيهم. بعد كده فيه نوعين من الـ scheduling، scheduling على مستوى الـ process، و scheduling على مستوى الـ threads. هنعرف تحت كل واحدة شغالة إزاي ومثال عليها طبعًا إن شاء الله، وفي الآخر طبعًا فيه sheet questions كالعادة.
مسائل بالحل بتاعها. الـ topic ده هنحل عليه السبت اللي جاي في نفس ميعاد الـ problem session إن شاء الله اللي هي الساعة 10 يوم السبت. السبت اللي جاي يعني إن شاء الله، بس طبعًا ما فيش محاضرات بس الـ session شغالة يعني عادي. طيب.
أشكال الـ multi-processor. الـ multi-processor ليها ثلاث أشكال. يا إما نسميها loosely coupled multi-processors، يعني devices، different computers، كل processor معاه its own RAM و devices.
فكأنهم أجهزة منفصلة، بتوزع tasks على الأجهزة دي، بـ communicate مع بعض، بتجمع أنت الـ tasks دي، بس في الآخر كل جهاز منفصل بذاته، معاه معاه resources بتاعته كاملة، عشان كده اسمها loosely coupled، يعني ما لهمش علاقة ببعض. بس بيكلموا بعض طبعًا.
ده وده بيبقى في شكل الـ clusters أو في شكل الـ cloud computers، كلها على الشكل ده. الشكل الثاني بنسميه functional specialized processors، ده بيبقى عندك main processor ومجموعة من الـ specialized.
processors إمكانياتها أقل من الـ main processor طبعًا، بس عددها كتير. وكلها مخصصة لـ functionalities معينة. أشهر مثال عليها يمكن كلنا نسمع عنه الـ GPUs، graphical processing units.
إيه الـ GPUs؟ مئات أو آلاف الـ processing units اللي كانت في الأساس مخصصة لمين؟ للـ graphical، للـ graphical user interface أو الـ graphical cards يعني. عشان الـ games كانت في الأساس، أو الحاجات اللي محتاجة graphics عالية.
بقينا بنستخدمها في calculations ثانية كتير، أشهرها الـ deep learning أو الـ AI عمومًا يعني. بقى بيستغل الـ GPUs دي في إنه يعمل processing massive processing عليها. هي طبعًا إمكانياتها أقل بكتير من الـ main processor بس عددها كتير. واللي بـ control ـها هو مين؟ اللي بيعملها controlling؟
هو الـ main processor. فده شكل ثاني من الـ multi-processors. الشكل الثالث اللي هو بنسميه tightly coupled processors، اللي هي اللي بنشوفها في الأجهزة بتاعتنا، عندك أكتر من processor اللي هو بنسميها الـ cores، كلها بنفس الإمكانيات، كلها على نفس الجهاز، فمعناها بيـ share.
الRAM والـ devices. وده اللي إحنا mainly بنركز عليه في محاضرة النهارده، إزاي الـ OS لأن هي دي اللي ممكن عليها decisions أكتر، لأن أنت في الآخر multi-processors بس بقية الحاجات كلها shared. فده ممكن اللي بنركز عليه أكتر.
في بقى نقطة مهمة تخص البرامج نفسها، علاقة البرامج ببعض، بنسميها الـ granularity أو اللي هو الـ rate of synchronization ما بين البرامج وبعضها. قد إيه البرامج بتحتاج بعض وهي شغالة؟ الموضوع ده مهم جدًا في الـ multi-processors. ليه؟
لأنه ببساطة أنهي أسهل لك كـ OS تـ schedule برامج ما لهاش علاقة ببعض ولا برامج بتعتمد على بعض؟ ما لهمش علاقة ببعض. لأن لما ما لهمش علاقة ببعض، أنت تقدر معاك حرية الـ scheduling، تـ schedule أي حد في أي وقت على أي على أي processor، مش فارقة.
لأنه ما لهوش علاقة ببعض، ما فيش dependencies بالظبط، عشان كده الـ factor ده مهم جدًا بنسميه الـ granularity. بيقسموا علاقات البرامج ببعض لخمس مستويات. من أول totally independent parallelism، ما لهمش أي علاقة ببعض، مرورًا بقى بـ very coarse، coarse، medium، لحد اللي بنسميها fine-grained.
parallelism. كل ما بتنزل تحت، معدل احتياج البرامج بيزيد، احتياجهم لبعض بيزيد، وبالتالي بيصعب على الـ OS الـ multi-processing أو الـ scheduling على الـ multi-processor. تعالوا ناخد فكرة سريعة عن كل واحد منهم، independent من اسمها. برامج totally ما فيش أي علاقة تجمعهم.
أشهر مثال على كده اللي بنسميه الـ time sharing. Time sharing systems اللي هو ممكن يبقى إحنا كذا user داخلين على نفس الجهاز، نفس نفس نفس الـ computer نفس الـ PC بس فيه بنـ share إحنا الـ time عليه، كذا user، user 1، user 2.
user n كلهم بيخشوا على الـ server ده أو على الـ device ده، كل واحد بـ execute البرنامج بتاعه، ممكن نـ execute نفس البرنامج يعني ممكن أكون كل واحد منهم مشغل الـ Word، بس هل في أي علاقة تجمعهم؟ ده totally different users. فهنا سهل على الـ OS إنه يـ parallelize أو يـ schedule البرامج دي براحته.
لأن ما فيش أي علاقة تجمعهم. Next، ثاني وثالث level اللي بنسميهم الـ very coarse والـ coarse، دول بيبقى synchronization على مستوى الـ processes. يعني البرامج نفسها بتحتاج تـ sync مع بعض.
بس على فترات متباعدة عشان اسمها coarse أو very coarse يعني على level عالي قوي، يعني فين وفين لما بيحتاجوا يـ sync مع بعض. مثال على كده مثلًا الـ Word والـ Excel والـ PowerPoint والحاجات البرامج بتاعت ال office أو أي برامج.
في لحظة ما ممكن يحتاجوا الـ print. بس مش دايمًا. بعضهم ممكن يحتاج الـ spell checker. مش دايمًا. ممكن تيجي أنت جوه الـ Word تـ insert table من Excel. ساعتها هتحتاج الـ Excel.
عشان لما أي تعديل هنا يـ reflect على الـ Word أو على diagram اللي مرسوم في الـ Word. بس ده في الوقت ده بس. مش دايمًا محتاجه إيه؟ مش دايمًا محتاجين بعض، فده اسمه coarse أو very coarse. فده بيبقى على مستوى الـ processes وسهل إن أنت تعمل ما بينهم multi-programming.
أو multi-processing. لأن هما برضه على فترات متباعدة بيحتاجوا بعض. الlevel الرابع بعد كده اللي بنسميه الـ medium-grained وده بيبقى الـ synchronization على مستوى الـ thread level. يعني على مستوى الـ threads اللي within.
نفس الـ process. طبعًا كونهم تابعين لنفس الـ process، فهم أكيد هيحتاجوا بعض. لأن نفس الـ process بيخدموا نفس البرنامج، بيـ share ما بينهم نفس الـ heap، نفس الـ stack، نفس الـ code.
نفس الـ global data، فأكيد هيحتاجوا يـ sync مع بعض. فهنا بنسميها medium-grained، هنا الـ scheduling بيبقى أصعب على الـ OS. خاصة بيـ schedule على مستوى الـ threads. لازم ياخد باله مين الحاجات اللي ليها علاقة ببعض عشان يشغلوا مع بعض.
الlevel الخامس والأخير ده نادر ما بيحصل يعني ده ده بيبقى حاصل بس في في بعض الـ specialized fragments من الـ computations يعني. بيبقى الـ parallelization على مستوى نفس الـ instruction stream، يعني نفس الـ function هي نفسها الـ function نفسها فيها instructions تعمل parallel.
وساعات بيبقى single instruction وبتشتغل parallel، هي الـ instruction الواحدة بتشتغل parallel أصلًا، هي واحدة بس بس بتشتغل parallel. بس ده نادر ما بنقابله إحنا يعني، ده ده بيبقى في specialized fragments يعني. ده ملخص للخمسة من من أول الـ independent.
لحد الـ fine-grained. ده الـ description بتاع كل واحدة اللي قلناه. يمكن بس نفرق ما بين الـ very coarse والـ coarse هما الاثنين ما بيحتاجوش بعض غير على فترات متباعدة بس الـ very coarse بيحصل في الـ distributed processing اللي هي الـ loosely coupled.
اللي هي بتبقى البرامج شغالة على totally independent computers. قد يحتاجوا يـ communicate مع بعض بس على فترات متباعدة. ده الـ very coarse. الـ coarse برضه برامج ما بتحتاجش بعض إلا على فترات متباعدة بس شغالة على.
جهاز واحد اللي هو سميناه tightly coupled. Tightly coupled اللي بيظهر فيه الـ multi-processing. بص بقى هنا معدل كل كام instruction بيحتاجوا بعض. طبعًا الـ independent ما بيحتاجوش. الـ coarse مثلًا يقول لك إيه؟ من 200 لـ 2000 instruction تلاقيهم يحتاجوا بعض.
يعني ده بيشتغل مثلًا up to 2000 instruction كده هيضطر يقف مستني حاجة من الثاني. الـ medium-grained مثلًا على مستوى الـ threads لأ ده من 20 لـ 200 instruction يعني مثلًا كل 20 30 instruction.
تلاقي الـ thread يقف عايز حاجة من الثاني. فده لما تيجي تعمل لهم scheduling، دول ما ينفعش يبقوا ورا بعض. لأن هما أصلًا مش هيلحقوا يشتغلوا.
وبعدين يحتاجوا بعض، يعني بيشتغلوا فترة صغيرة وبعدين يحتاجوا بعض، فما ينفعش تشغلهم ورا بعض. هتلاقي كل واحدة حتى مش هتكفي الـ quantum بتاعتها يعني لما تدي لها quantum، تلاقيها ما بتلحقش تخلص الـ quantum دي قبلها هتروح واقفة عايزة حاجة من الثاني. فالأحسن إن أنت تعمل لهم scheduling.
مع بعض parallel مع بعض بالظبط هنا الـ decision فرق في الـ medium-grained لكن لو كانوا independent على بعض براحتك مش هتفرق خالص. فده كان أشكال الـ multi-processing وعلاقات البرامج ببعضها. ده بيسمع بقى فيه.
ثلاثة design issues المفروض الـ OS ياخد باله منهم أو لازم ياخد قرار فيهم. في three design issues مسؤولية الـ OS. هنشوفهم على رسمة يعني. assume إن أنت عندك مجموعة برامج وعندك multi-processor.
الـ السؤال الأولاني لازم الـ OS يجاوب عليه، مين يروح فين؟ مين من البرامج يروح على فين من على أنهي processor؟ مين يروح فين؟ ده مسؤولية الـ OS. السؤال الثاني.
على مستوى الـ single processor. كل processor منهم هل محتاج تبدل ما بين البرامج اللي على الـ processor ده ولا لأ؟ اللي هي بنسميها multi-programming. هل محتاج تـ multi-program كل processor ولا أحسن لك تشغل البرنامج لحد ما يخلص؟
ده سؤال الـ OS المفروض يجاوب عليه. الـ design issue الثالثة، لما تيجي تختار من الـ pool ده، تختار مين next؟ مين اللي تختاره next؟ هل first come first serve؟ هل الـ shortest؟ هل round robin؟ هل الـ highest priority؟
تختار مين اللي هي الطرق اللي خدناها في المحاضرة بتاعة الـ single processor بالظبط. فثلاث أسئلة دول لازم الـ OS يجاوب عليهم. الفكرة إن الإجابة مش مباشرة. ما فيش إجابة واضحة كده صريحة، أه لازم أعمل ده، أه لازم أشتغل بالطريقة دي، لأ.
زي ما اتعودنا من بداية الـ term، إن الـ OS مليان decisions. وطرق مختلفة، كل حاجة ميزة وعيب، وعلى حسب الـ OS اللي أنت ده بتعمله بيخدم مين، ساعتها بتختار.
الحاجة المناسبة. فمثلًا إجابات الأسئلة دي معتمدة على نقطتين أساسيتين. عندك كام processor؟ وعلاقات البرامج ببعض. بمعنى لو أنت عندك آلاف الـ processors، processors كتير.
محتاج تـ multi-program الـ processor واحد؟ بالعكس. ده أنا لو هـ multi-program لو هبدل، أنا كده بخسر أكتر ما بكسب. بخسر إيه؟ حد يعرف؟ حد عارف يرفع إيده. ال caching بالظبط، بخسر الcaching . بخسر وقت الـ save والـ load، الـ switching.
كل ده بخسره، فأنا لو عندي processors كتير أحسن لي أـ schedule non-preemptive. خلاص؟ ده بالنسبة للإيه؟ للـ multi للـ سؤال طيب، الـ granularity. لو البرامج.
لو أنت بتـ schedule medium-grained، يعني threads بتحتاج بعض. أحسن لك تـ schedule واحدة ورا الثانية ولا مع بعض؟ مع بعض، ده اللي قايلين، تـ schedule مع بعض، لأن مع بعض هما يحتاجوا بعض. لكن هما مش معتمدين على بعض، ودي أي حد في أي حتة في أي وقت، مش فارقة.
يبقى هنا القرار ده فرق على أساس ده وعلى أساس ده. فالقرارات دي مش مش مش معاك حرية يعني هي بتعتمد على عدد الـ processors وعلى طبيعة البرامج اللي عندك.
تعالوا بقى نيجى لكل نقطة بعض التفاصيل عنها أولاً مين يروح فين الـ Assign بتاع الـ Processes ع الـ Processors إحنا لو تفتكروا إحنا شغالين على Tightly Coupled إن فرضين إن كل الـ Processors بنفس الإمكانيات وبيشيروا الـ RAM و الـ Devices و الـ ...
فبما أنهم بنفس الإمكانيات، مش فارق مين يروح فين، مش فارق، معهم كلهم نفس الإمكانيات، فتعتبر عندك pool of processes و pool of processors، ودي أي حد في أي واحد، مش فارق، إيه اللي يفرق؟
اللي يفرق طريقة الـ assignment نفسها، هل بتودي الـ process على الـ processor statically؟ يعني هتروح على الـ processor وتفضل عليه ولا dynamically؟ يعني ممكن تروح على ده شوية تخرج وترجع على واحد ثاني.
تخرج وترجع على واحد ثالث. ما ما تنسوش إن الـ process بتعمل حاجة من اثنين أثناء الـ lifetime بتاعتها. أيوه. يا I/O. أما بتروح I/O ترجع ثاني، ترجع فين؟ بالظبط. الـ static يقول لك ترجع على نفس الـ processor. الـ dynamic على أي واحد على حسب المتاح.
هو طبعًا الcaches الcache طبعًا هي هي الcache دي hardware decision خلي بالك يعني مش في إيد الـ OS قوي. فالcaches عادةً بتبقى فيه مستويات من الcaches  بتبقى مخصصة لكل processor.
وفي caches بتبقى shared ما بين الـ processors لأ ما ما بين الـ processors وبعضها. يعني level one ده بيبقى دايمًا مخصص للـ processor، كل processor عنده level one cache بتبقى صغيرة قوي سريعة قوي.
Level two or three بيبقى shared ما بين الـ processors، بيبقى أبطأ وأكبر وshared. بس ده الـ OS ما لوش دخل في القرار ده، ده مصنع الـ hardware هو اللي بياخد القرارات دي. طيب، الـ static بقى، الـ static assignment فكرته إيه؟ زي ما قلنا.
بتودي كل process عنده الـ queue الخاص بيه، تودي كل process على processor، تفضل عليه. حتى خرجت ورجعت على نفس الإيه؟ على نفس الـ processor. ميزة حاجة زي كده أولًا كل processor عنده الـ queue الخاص بيه.
فما عندكش مشكلة competition على الـ queues. يعني أنتوا لو تفتكروا في في الـ OS بتاعنا إحنا عاملين lock على الـ queues. الـ queues shared. هنا مش shared. هنا كل واحد عنده الـ queue بتاعه، كل processor عنده الـ queue بتاعه.
هو هو ده طبعًا طبيعي لأن إحنا multi-processors فطبعًا هو هو بقدر أشغلهم parallel أنا عندي كذا processor. بس الميزة الثانية إن بس الـ decision اللي باخده.
باخده إمتى؟ قرار مين يروح فين بيتاخد إمتى؟ في الأول خالص. فلان هنا، فلان هنا، فلان هنا، خلصت. أه كلهم بيخرجوا ويرجعوا. يبقى الـ overhead بتاع اتخاذ القرار ده على الـ OS قليل، بتاخد مرة واحدة في الأول.
الميزة الثالثة الcache، بستفيد من الcache لأنه ما بيخرج هو على نفس الـ processor، فلو مكاش بعض الـ content حتى لو لف ورجع احتمال يلاقي الـ content بتاعه على نفس الـ processor. الميزة الرابعة إنه بيسهل عملية اللي بنسميها group scheduling.
أو gang بيسموها gang scheduling. اللى قلناها من شوية مش إحنا قلنا لما يبقى فيه، لو عندك كذا thread مرتبطين ببعض اللي هو الmedium اللي هو الmedium-grained اللي هما اللي مرتبطين ببعض، أحسن لك تعمل لهم scheduling إيه؟ ده بيسهل لك ده، يعني لو عندك مثلًا أربعة مرتبطين ببعض ودي كل واحد على.
processor بس وخلصت. فلما يشتغلوا يشتغلوا مع بعض. يبقى ده بيسهل عملية الـ group أو الـ gang scheduling. عيبه إيه بقى الواضح؟ ما فيش load balancing بالظبط. ممكن processor الضغط اللي عليه خف قل.
فبقى فيه processor قاعد idle وبقية الـ processors مشغولة بسبب إن أنت قرار ده اتخذته بس مرة في الأول. خلاص.
storage على إيه؟
الcache ممكن طبعًا لو فيه ضغط هيخسر الcache ساعتها. يعني ما هي الcache بتkeep الmost recently used، فممكن لو لو فيه برامج كتير على نفس ال processor.
البرنامج أما هيرجع ثاني يكون خسر الcache، وارد. بس ده تحت شرط إن هو يكون فيه برامج كتيرة على، لكن عكس عكس مثلًا اللي هيحصل في الـ dynamic هنتكلم عنه دلوقتي. مصطفى إيه طيب؟ محمد.
يعني هنا اللي هيحصل إيه؟ في الـ dynamic، الـ dynamic هو single queue. بالظبط single queue وكل مرة لازم تاخد قرار مين يروح فين. واللي بيخلص بيخرج ويرجع أيًا كان السبب بيرجع على الـ queue وياخد تاخد القرار مرة تانية
فهنا ميزته الأساسية إنه بتقدر أه أه بتقدر تـ balance ما أنت قدامك الـ processors كلها وكل مرة بتاخد القرار، فتقدر تـ balance الـ load على الـ processors. هو عكس الثاني تمامًا، يعني عيبه أولًا shared shared queue. ف.
الـ queue ده ممكن يعمل لنا bottleneck. أنت ممكن أكتر من processor يقروا في نفس الوقت ممكن يسحبوا نفس الـ process في نفس الوقت، فلازم يحصل على الـ queue ده protection، critical section. الcache أنت مش ضامن هنا بقى يعني هنا أنت أكيد احتمالية إن أنت ترجع أصلًا على نفس الـ processor ضعيفة. فأنت في الغالب أنت بتخسر الcache بتاعك.
الـ Overhead عالي لان القرار الـ Overhead بتاع Decision بتاخد الـ Decision ده ايه كل مرة مش مرة واحدة في الاول كل مرة بتاخد الـ Decision بتاع مين يروح فين بيصعب بظبط بيصعب عملية الـ Gang او الـ Group Scheduling لان انت
أنت القرار بتاخده كل مرة، فأنت ما تضمنش إن اللي عايزين بعض هيشتغلوا parallel مع بعض. هو طبيعته مش كده. طبيعته إنه على حسب اللي فاضي بوزع عليه. فهو عكس الثاني تمامًا.
still تبع نفس النقطة دي بس شكل ثاني من الـ assignment، اللي هو الـ kernel والـ user. إحنا عارفين إن فيه نوعين برامج، kernel والـ user programs، الاثنين code ومحتاجين scheduling. ففيه شكلين من الـ assignment هنا للـ kernel مع الـ user.
يا إما master-slave، يا إما بنسميها peer-to-peer
. Master-slave يعني إيه؟ من اللي هي بنسميها المركزية، centralized organizations، إن أنت دايمًا عندك master processor.
بـ run عليه الـ kernel اللي هو الـ master program. كل حاجة بتتم من خلاله. عايز تـ schedule على الـ processors، تـ schedule من خلال الـ kernel. عايز تـ request أي I/O أو أي task، بتـ request.
من الـ processor الرئيسي، فكله بيتم من خلال الإيه؟ النقطة المركزية دي. طبعًا مشكلة الحاجات المركزية دي إيه؟ الضغط عليها كبير، الضغط عليها كبير. فبيسبب حاجتين، لو الـ.
أولًا bottleneck على الحاجة دي، لأن الضغط كبير. والحاجة الثانية إن لو الـ master ده processor وقع لأي سبب، الـ system كله بيقع. الـ system كله بيقع، لأن الـ master وقع. وقع ده ممكن أبسط حاجة overheating.
الـ processor أما بيسخن قوي، بيفصل. لو فصل الـ system كله بيقع. والحاجة الثانية إن هو بقى performance bottleneck إن كل حاجة بتتم من خلاله. وده حتى اللي بنشوفها حتى على فكرة في في الـ organizations يعني عمومًا، أنت لو لو بتروح مصالح حكومية.
أو أي مصلحة فيها فكرة الـ centralization دي، دايمًا هتلاقي طابور. لازم. مين؟ أه طبعًا shared، ما هو بيطلبوا منه كل حاجة.
بس لازم كل حاجة تتم من خلاله. ما فيش قرارات بتتاخد على مستوى كل processor لوحده. مش كده master-slave. الtime بتاع إيه؟ ما هي دي الـ performance bottleneck. بقى فيه، ما هو عايز يخدم على الكل.
هو ميزته إيه؟ هو مسيطر يعني هو بيmanage كل حاجة، بس نتيجة إن أنت بتmanage  كل حاجة، بقى فيه بطء وبقى فيه bottleneck يعني فيه اختناق على على الحاجة المركزية دي.
أه هي كل حاجة في إيديك، كل حاجة تحت سيطرتك، بس نتيجة ده بيحصل bottleneck. العكس بقى الـ peer-to-peer اللي هو النظراء يعني، كل الـ processors على نفس الـ level، الـ kernel يقدر يروح على أي حد ويقدر ينقل من أي processor لأي processor ثاني، مش مشكلة.
الفكرة بقى في إيه؟ إن الـ scheduling مش من خلال الـ processor اللي عليه الـ kernel، لأ. ده كل processor أما بيفضى، الـ dispatcher، الـ scheduler بيشتغل عنده ويschedule الـ next. يبقى قرار الـ scheduling نفسه اتوزع على.
الـ Processors كل ما الـ Processor يفضل الـ Scheduler يشتغل عليه عشان يـ Schedule الـ Next فما بقيتش مركزية بس طبعاً دا بيوصع أو بيعقد دول الـ OS دلوقتي
ما ده shared دلوقتي. أنت دايمًا لما تبقى الحاجة مركزية في إيد شخص واحد هي very controlled. كل ما بتتوزع كل ما بتحتاج تmanage وتsync أكتر ما بين الحاجات دي وبعض، مثلًا ممكن ده shared queue صح؟
وكل processor يقدر يسحب وقت ما يفضى، ممكن الاثنين يسحبوا نفس البرنامج، وييجوا يمسحوا، كل واحد يروح ماسح برنامج. يبقى يحصل إن برنامج اتمسح من غير ما يترن، وبرنامج يشتغل مرتين. نتيجة إن القرارات دي بتتاخد، كل واحد بياخد القرار بنفسه.
طب عشان أحمي حاجة زي، أحمي حاجة زي كده محتاج أعمل إيه؟ Lock، critical section على الـ queue دي. نتيجة الـ critical section ده، ممكن طبعًا ده أو على الأقل هيحصل برضه لو الـ processors كتير هيحصل bottleneck، performance bottleneck على على الطابور ده.
لو كلهم بيطلبوا في نفس الوقت مش هيجيبوا في نفس الوقت هيقفوا طابور والحاجة الأخيرة أن حتى الـ request بتاع الـ devices أو أي requests ما بقيتش برضو من خلال الحاجة المركزية كل واحد بيـ request من ذاته يعني أنا دلوقتي ده محتاج device بيـ request
الـ OS يشتغل عليه request، زي request. فمحتاجين يـ sync مع بعض الـ requests دي. يعني processor بيطلب الـ print. Processor ثاني عايز برضه الـ print. ما هي printer واحدة. لازم يـ sync مع بعض. قبل كده ما كانش الموضوع ده موجود، في الـ master كلهم بيطلبوا من الـ master، فالـ master عارف.
لكن دلوقتي هما محتاجين يكلموا بعض، محتاجين يـ sync مع بعض. هتلاحظ كل حاجة وليها الميزة والعيب بتاعها. طيب، ده كان أول قرار للـ OS اللي هو مين يروح فين؟ قلنا مش فارقة بس في شكلين.
أروح static ولا dynamic؟ وأودي الـ master سوري أودي الـ kernel والـ user إزاي؟ هل master-slave ولا peer-to-peer؟ ممكن يروح ينقل عليه، بس بس الفكرة إن أنت.
الفترة اللي هينقل فيها ما هو هو وقع أصلًا. أصل أنت عشان تنقل ما هو أنت في الآخر ده code وكان فيه حاجات على الـ cache وحاجات على الـ registers يعني فأنت هوب.
الـ processor ده shut down أصلًا. فأنت محتاج يعني عشان تعمل حاجة زي كده بيسموه، بتحتاج يبقى عندك دايمًا إيه؟ backup يعني عندك processor ما لهوش أي دور غير إن هو كل شوية ياخد.
نسخة من الـ processor ده، بس هو دوره كده إنه backup يعني. فأنت خسرت processor يعني، بس أه ممكن يعني لو systems كبيرة وفيها processors كتير ممكن تعمل حاجة زي كده. بتعمل أكتر على الـ hard disks كمان. طيب، الـ decision الثاني.
اللي هو هل محتاج تـ multi-program ولا لأ؟ قبل ما نجاوب على السؤال ده هو الـ multi-programming اللي هو إن أنت تبدل ما بين البرامج على على processor واحد. ده عادةً تحتاجه فين؟ في الـ static ولا في الـ dynamic؟ واضحة، في الـ static. الـ dynamic أنت كده كده عمال بتوزع.
وبتbalance، لكن مشكلته أكتر، احتياجه أكتر في إيه؟ في الstatic إن هو كل processor خلاص بقى عليه طابور من البرامج لازم يتصرف. فقرار الmulti programming مهم عند الإيه؟ عند الstatic أكتر منه عند إيه؟ طيب.
في الـ static أـ multi-program ولا لأ؟ على حسب. بس هو بشكل عام الـ multi-programming أفضل ولا أسوأ؟ حسب برضه. الـ multi-programming هو أفضل من ناحية الـ interactive environments. دايمًا فيه responses، البرامج دايمًا بتديك responses.
ما فيش إن لو برنامج كبير اشتغل الأول عايز خمس ساعات وجه برنامج وراه عايز نص دقيقة، النص دقيقة ده هيستنى الخمس ساعات. ده الـ non-preemptive. لكن لو أنت بتـ multi-program كل البرامج هتديك responses.
بس طبعًا عيبه عيوب الـ context switching والـ overhead بتاع الكلام. بس في الآخر لو أنت static والبرامج ما فيش علاقة ما بينهم، فأكيد تـ multi-program أفضل من الـ single من من الـ non-preemptive.
لو أنت static والبرامج ما لهاش علاقة ببعض، الـ multi-program أفضل في الحالة دي. ليه؟ علشان البرامج كلها تـ response. ما هو أنت كده كده البرامج خلاص بقت ثابتة على الـ processor ده. لو أنت مش بتـ multi-program آخر برنامج جه
هيضطر يستنى كل اللي قدامه، لو اللي قدامه بقى دول بياخدوا توقيتات كبيرة، ساعتها البرنامج الأخير ده هيبقى الـ response time بتاعه سيء جدًا. الـ throughput هيبقى سيء. كم الـ outputs اللي بيطلعها. فالـ multi-program هنا أكيد أفضل وأسهل لك لأن أنت البرامج.
مش محتاجة بعض. يبقى ده الإجابة هنا sure ليه؟ علشان أستفيد better utilization وhigh performance. أو high utilization better performance. وده ليه؟ عشان البرامج ما لهاش علاقة ببعض. طيب.
لو هم بقى medium أو fine-grained هنا الموضوع مش واضح قوي وضوح ده على حسب factors تاني يعني
لو عندك processors كتير لأ، لأ لأ لأ بالعكس. بالعكس ده أنا أـ schedule الجروب مع بعضه وأسيبهم يشتغلوا للآخر مع بعض أحسن ما أقعد أبدلهم. ليه؟ أنا لما أشغلهم كلهم مع بعض، أما بيحتاج حد يلاقيه. أه يلاقيه، ما فيش إن هو إيه؟ خرج وأضطر أستناه.
ده لو عندي processors كتير، فهنا الموضوع discrete. ده يديني performance أفضل من لو كنت قعدت أبدل مع بعض. بسبب إنهم بيحتاجوا بعض، بيحتاجوا بعض كتير. السؤال الأخير بقى للـ OS أختار مين؟
إحنا شفنا إن موضوع الاختيار ده كان فارق جدًا ساعة الـ uni-processor، صح؟ كان مين أفضلهم تفتكروا؟ أولًا كان مين الأفضل كـ response؟ الـ non-preemptive ولا الـ preemptive؟ preemptive. كان مين أفضل حاجة في الـ preemptive؟
الـ round robin كان practical أكتر. الأفضل كان اللي قبله اللي هو shortest remaining time. لو كل ما يجي حد يوصل أوقف وأشغل الصغير. فدايمًا throughput عالي.
بخلص كتير، دايمًا الـ response time قليل لأن كله بيشتغل وبفضل الصغيرين، بس كانت مشكلته الأساسية طبعًا ما أعرفش الـ service time، محتاج أ estimate وده مش سهل، ومش دايمًا بعرف أعمله.
ده كان عند الـ single processor، الغريب بقى زي ما هنشوف next إن شاء الله إن على الـ multi-processors ممكن simple approach زي الـ first come first serve اللي هو queue عادي خالص يديك performance كويس جدًا، وبـ overhead منعدم تقريبًا.
هو first come first serve. لو تفتكروا first come first serve ده كان أسوأهم ساعة الـ single processor. هنا العكس، ممكن approach زي ده بسيط يديك performance أفضل بكتير زي ما هنشوف next أما نتكلم عنه. في أي سؤال يا شباب؟
حد عنده سؤال ده فين؟ ما هو طبعًا ده مشكلته إن أنت موضوع الـ estimation بتاع الـ service time، ما هو ده overhead.
عشان تعرف estimate البرنامج هياخد وقت قد إيه؟ ده overhead في حد ذاته ومش دايمًا بتعرف تعمله لكل البرامج. فدي نقطة. النقطة الثانية إن إن أصل زي ما هنشوف حالًا في كدراسة اتعملت يعني إنه أصلًا فكرة الـ multi-processor.
قرار إن أنت تختار الصغير ده أصلًا ما بقاش فارق. يعني يعني هيكلفك overhead عالي، والاستفادة منه مش قد كده، مش قد الثمن اللي بتدفعه يعني
حد عنده سؤال ثاني يا شباب؟ طيب. نيجي لـ، فيه شكلين بقى من.
الـ scheduling اللي على الـ multi-processor، يعني أنت عندك كذا processor أهو، وعندك كذا برنامج. دول processes ودول CPUs. في إن أنت تـ schedule على مستوى الـ process نفسها، يعني الـ process كاملة.
تروح على processor. طب ولو فيها أكتر من thread؟ لأ، الـ اللي على مستوى الـ process، كل الـ process راحت على الـ processor ده، الـ threads بقى تبدل على الـ processor ده. فده الشكل ده من الـ scheduling.
ما فيش parallelize أو parallelism على مستوى الـ single application. يعني الأبليكيشن الواحد ما بيشتغلش parallel. لأن هو كله راح على single processor. الـ thread scheduling لأ العكس، بتـ schedule على مستوى الـ thread فممكن.
two threads من نفس البرنامج على two different processors. فمين الأفضل كـ parallelism؟ الـ threads scheduling. وده اللي بيستخدم mostly في معظم الـ operating systems، منها الـ Windows والـ Linux مثلًا. بيشتغلوا scheduling على مستوى الـ threads، مش على مستوى الـ pro.
cessor الأول ناخد اللي على مستوى الـ process. رأيكم ده أحتاجه إمتى؟ static ولا في الـ dynamic؟
في الـ dynamic، في الـ dynamic ليه؟ هو الـ dynamic اللي بحتاج كل شوية يطلعوا ويخشوا أضطر آخد decision ثاني، يطلعوا ويخشوا أضطر آخد decision. فـ أه بحتاجه أكتر فين؟ في الـ dynamic. الـ static أنا مش محتاج أصلًا decision.
يعني الـ static أنا خدت الـ decision في الأول. أنت روح هنا وأنت روح هنا وأنت روح هنا وانتهى الموضوع. ما ده بحتاجه أكتر في الـ dynamic. اللي هو بيبقى عندي single queue.
وبعد أختار منهم كل مرة. أو لو عندي priorities، كنا بنعمل إيه في الـ priorities لو عايز أعمل priorities؟ أبسط فكرة للـ priorities؟ كل واحد queues، بعمل كل واحد queue بالظبط، كل واحد queue. طيب، ده ده بقى اللي كنا بنتكلم عنه.
إن قرار أختار مين ما بيفرقش قوي في الـ multi-processors.
 Simple approach زي الـ first come first serve ساعات بيبقى كافي جدًا، ودي دراسة اتعملت حتى من فترة يعني. مقارنة ما بين ثلاث طرق.
طريقتين أسف طريقة non-preemptive، وطريقتين preemptive منهم الطريقة اللي تعتبر كانت الأفضل في الـ في الـ preemptive اللي هي الـ shortest remaining time. كان بيقارن الـ first come first serve قصاد الطريقتين دول.
قارنهم مرة على single processor، ومرة على بس two processors بس، يعني يعني مش مش processors ده بس على two processors. إيه بقى المقارنة؟ الـ x-axis كان عليه.
بيسموها الـ coefficient of variation ما بين البرامج. بنشغل برامج كتير بس باختلاف الـ service times بتاعها. Coefficient 0 معناها إن البرامج اللي شغالة كلها نفس الـ service time. كلها بتاخد نفس الوقت.
كل ما بيعلى في الـ x-axis، كل ما الـ variety ما بين الـ service times في البرامج اللي بيجربها بتختلف، كل ما يوصل خمسة معناها فيه wide variation من الـ service في الـ service time ما بين البرامج، فيه برامج صغيرة قوي، برامج كبيرة قوي، برامج بتحتاج I/O كتير، برامج بتحتاج processor كتير، يعني varieties كتير.
الـ y-axis بقى عليه إيه؟ نسبة الـ throughput ما بين الـ round robin للـ first come first serve. الـ throughput لو تفتكروا تعريفه، كم الـ outputs اللي بطلعها في الـ unit of time. فكل أما الرقم ده يكبر.
كل معناه انك بنتك احسن بالصدق فالنسبة دي لو بواحد معناها زي بعض ان الراوند روبين زي الفرس كم فرسه كلما نسبة دي تعلى اسوأ يعني الراوند روبين افضل وده المتوقع
في البرامج المتبقية، أما كانت البرامج كلها لها نفس الوقت، لم يكن هناك فارق في الـ Outputs ما بين First-Conference Serve والـ Exchange between them.
أما بدأت تغييرات هذا يأتي لفرق يبين على مستوى الـ Single Processor وصل هنا لـ تقريبا 1.15 1.15 يعني الـ Round Robin أفضل بـ 15% عن First Conference Surf أما كانت هي
سجل البروسيسور اما كنت على 2 بروسيسور بس يعني بس زودت البروسيسور واحد الفرق ده وصل تقريبا 1.04 يعني راوند روبين افضل بس بنسبة 4% ايس بقى مشاكل الراوند روبين؟
مقارنة بسهولة الـ first-conference Round-robin في كونتكست السويتش كتير Overhead كتير بتخسر الكاش نتيجة السويتش فيعني طريقة بسيطة ادت لك performance قريب من Round-robin رغم سهولتها وبساطتها
ما تنساش ده كان على إيه؟ بس على اثنين يعني ما ما بتتكلمش على لأن الدراسة دي كانت قديمة يعني فأنت بتتكلم على دلوقتي بيبقى عندك الموبايلات بتاعتنا دي فيها 8 و16 وساعات 32 processor، بعض الموبايلات دي. فأنت بتتكلم أصلًا في في فرق كبير. طيب.
ده كان ما بين الـ first come والـ round robin. طب ما بين الـ shortest remaining اللي هي كانت الأفضل ساعة الـ single processor، برضه على مستوى الـ single processor فرقت، وصلت لـ تقريبًا 20% تحسين، 1.2.
ده على مستوى الـ single processor. بس still برضه على مستوى الـ dual processor كان 1.06 تقريبًا. قيس بقى الفرق ما بين الـ first come first serve اللي هو أصلًا.
queue عادي، اللي جه الأول بيخش، وما بين الـ shortest remaining اللي هو بقى فيه إن أنت لازم تـ estimate الـ service time من الأول، وكل أما يجيلك برنامج جديد لازم توقف وتختار مين اللي فاضل له وقت أقل.
شوف كم الـ Overhead اللي بتعملوا هنا قصاد السهولة اللي هنا والperformance gain اللي انت كسبته على  processor 2
 6% أو 5% فملخص ال slide دي ايه بظبط الdecision ده مش فارق ايه السبب هنا ايه الفكرة اللي ورا الموضوع
أنت عندك كذا processor والبرامج بتجيلك في توقيتات مختلفة، فاحتمالية إن أنت برنامج ياخد processor وقت كبير مش هيعمل لك مشكلة قوي، لأن أنت أما يجيلك برنامج ثاني فيه احتمال كبير إن أنت تلاقي processor ثاني متاح.
تقدر تشغل عليه. عشان كده الطريقة ما بقتش فارقة قوي، طريقة اختيار مين اللي يروح 

next. لأن أنت في الغالب هتلاقي حد متاح. ده أنت عندك 

processors كتير، وتوقيتات خروج ودخول البرامج.
وده مثال يثبت لنا ده، فاكرين المثال ده شفناه بالتفصيل في المحاضرة رقم 6 اللي قبل الـ midterm. حلينا عليه كل الطرق. كان منهم الـ first come first serve. هنحلها هي هي المرة دي بس على.
two processors بنفس الـ configurations الباقية، time now zero، وعايز نحسب نفس نفس الأرقام دي كلها، خلاص؟ بصوا بقى، عشان بس تبقوا واخدين بالنا من اللي هيحصل، أما كنت على one processor كان الـ average.
normalized turnaround time كان 2.5 تقريبًا. يعني كان متوسط تشغيل كل برنامج بيضطر يستنى يقعد في الـ system مرتين ونص وقته، وده كان يعتبر من الأسوأ
ساعة المثال ده في الـ first come first serve. هي هي الطريقة بس خليناها على 2 processors. تعالوا نtrace، الtracing سهل جدًا، نفس اللي عملناه في الـ single processor. دلوقتي عند time 0 مين اللي وصل؟ الـ A عايزة 3، مين المتاح؟
الاثنين متاحين، الاثنين متاحين عند time 0 أهو. Schedule على أي واحد، بس علشان نوحد الإجابة ساعة ما بنحل بقى في امتحانات أو كده، بنختار دايمًا بالترتيب، يعني الأول.
فاللي يليه فاللي يليه، خلاص؟ فهنا الـ A هت schedule على processor رقم واحد، هتاخد قد إيه؟ ليه؟ ثلاثة، والطريقة دي non-preemptive. هتشتغل لحد ما تخلص.
يبقى الـ A دخلت على الـ processor ده وهتشتغل لحد ما تخلص. عند time two مين وصل؟ عايزة ستة. الأولاني مشغول بس الثاني. هو ده اللي كنا بنتكلم عليه. الثاني متاح، ا schedule  على الثاني. يبقى هنا الـ B.
تاخد من كام؟ من اثنين هتاخد الستة بتوعها من اثنين لثمانية. ده الـ B. يبقى الـ A خلصت عند ثلاثة والـ B خلصت عند ثمانية. أثناء ده مين وصل؟
الـ C. عند time أربعة الـ C وصلت عايزة كام؟ عايزة 4. عند time 4 كان الـ processor ده متاح، ا schedule على طول مش هتستنى. هتschedule  من 4 لحد 8.
ده الـ C من 4 ل8، وكده الـ C برضه خلصت عن 8. الـ D عند time 6، الـ D وصلت وعايزة 5. ده مشغول عليه الـ C، والثاني مشغول عليه. أهو ده مشغول.
وده مشغول. هتستنى بعد ما. ده non-preemptive، فهتضطر تستنى. هتستنى أول واحد يخلص، الاثنين خلصوا في نفس الوقت خلاص. بschedule على الأولاني. يبقى هسكيدول الـ D تاخد من 8 لـ 13.
والـ D خلصت عند 13. الـ E جت عند time 8. الثاني فاضي، هschedule من ثمانية لـ 10.
تعالوا بقى نحسب نفس الـ factors، نفس الرقم اللي فوق ده، الأول الـ turnaround time، اللي هو الـ finish ناقص الـ arrival. خلص عند 3، كانت واصلة عند صفر، استنيت 3 من أصل service time 3، يعني ما استنيتش، جت اشتغلت.
الثانية خلصت عن 8 وكانت واصلة عند 2، يعني قعدت في الـ system ستة من أصل 6، يعني ما استنيتش. خلصت عند 8، كانت واصلة عند 4، قعدت في الـ system
 4 من أصل ال4 بتوعها.
جات اشتغلت ما استنتش 13 وكانت وصلة عند 6 يعني قعدت 7 من أصل 5 . 7 من أصل 5 يعني 1
و 4 من 10 finally دي خلصت عند 10 كانت توصل عند 8 قعدت 2 من أصل 2 يعني 1 تحسب average دول يطلع تقريبا 1 من 10
مقارنه بكام بقى؟ هي هي نفس الطريقة. مجرد ما قلبتها two processors، نزلت من ان البرنامج بيقعد مرتين ونص وقته، الى مره وكذا، يعني تقريبا كلهم ما عدا واحده.
مفهومه الفكره؟ في دي الفكره. ان ايه اللي حصل هنا؟ ان انت نادر جدا اما ان هتلاقي سيناريو تيجي process تلاقي كل الـ processors مشغوله. او حتى لو كانت مشغوله استنى وقت ولا ايه.
هشتغل على واحد منهم فدي الفكره بتاعه الـ multiprocessor. ده كان الـ first come first serve. طبعا هو مفيش احسن من يعني الاحسن من one point one average هو one يعني one. فهسيب لكم ده تجربوه وتشوفوا ده هيطلع كام مع اخذ بقى في الاعتبار ان ده
أصلًا complex في الـ implementation بتاعه. لإن ده shortest remaining time اللي هو محتاج اعرف الـ service time مسبقًا التاني ما كنتش عايز مش محتاج اعرف. خلاص؟ في أي سؤال هنا؟ ده الـ quiz.
الصوت لو سمحتوا يا شباب، الصوت. طيب الطريقة التانية في الـ scheduling على مستوى الـ thread، طبعًا فكرة الـ threads قلنا ان هو عندك كذا function شغالين في نفس الوقت بيـ share الـ code والـ data وال..
والـ Heap والـ Stack، sorry الـ Heap بس الـ Stack كل واحد عنده its own stack. طبعًا كونهم شغالين تبع نفس الـ process فأكيد هيحتاجوا بعض كتير بالتالي ده اللي سميناه medium-grained granularity أو medium-grained parallel.
طبعًا هنا لو أنت عملت scheduling على مستوى الـ thread في dramatic gain of performance هتحصل عليه مقارنة بالـ single processor لو أنت كنت بتـ schedule على مستوى الـ threads عنه حتى مقارنة لو أنت بتـ schedule على مستوى الـ processes.
وخلي بالكم ان الموضوع ده موضوع الـ multi-threading والـ concurrency وحلولها المشاكل بتاعتها ده مش مرتبط بالـ course يعني الـ topic ده مهم لحضراتكم في شغلكم بعد كده. لأن نادر جدا ما هتلاقي شغل في شركات ناس شغاله single thread.
ما هو ببساطه اللي شغال single thread ده هو حكم على نفسه انه خسران بقيه الـ processors من غير ما يعمل اي حاجه زياده يعني هو بس مجرد ما تقلب كودك multi-threaded انت بتسرع البرنامج بتاعك بدون algorithm.
بس بتحتاج تـ resolve الـ concurrency issues اللي اتعلمنا بعضها خلال المحاضرتين أو ثلاثة اللي خدناهم مع بعض. فالـ topic ده مهم جدا سواء الـ theoretical part بتاعه أو الـ practical على قد طبعا ما خدنا في المعمل.
على مستوى \.NET يعني أو C#، طبعا ممكن تتعلموا على مستوى لغات تانية. المهم. في هنا أربع طرق في الـ multi-thread في الـ schedule على مستوى الـ threading يعني. ناخد فكرة عن كل واحدة وبعدين على حسب بقى الوقت هنشوف trace على حسب ما الوقت يكفي يعني. الطريقة الأولى الـ load share.
الـLow Chair معناها الـThreads كلها بتتحط في Single Cue كل الـProcessor أما يبقى فاضي يschedule الـNext Thread Low Chair كلهم بصين على نفس الـqueue
كل أما processor يفضى يـ schedule الـ next thread مش الـ next process. next thread. الطريقة التانية gang scheduling ودي اتكلمنا عنها. لما بتيجي تـ schedule الـ related threads لازم يحصلهم scheduling مع بعض بس في شكل preemptive.
يعني يخشوا مع بعض يشتغلوا time slice معين بعدين كلهم يخرجوا مع بعض. تخش مجموعة تانية تشتغل time slice معين وبعدين يخرجوا وهكذا. فده preemptive version بس بتـ schedule gang أو group.
الطريقة التالتة strict version من الـ gang، اسمها dedicated processor assignment. أولًا، لازم يبقى عندك عدد processors تكفي عدد الـ threads بتاعت البرنامج. بتعمل ايه بقى؟ يجي البرنامج يشتغل هو عايز خمسة threads.
تروح مديله خمسة processors معاه لحد ما يخلص. فده non-preemptive version، هي gang برضو، بتـ schedule كله بس non-preemptive. dedicated عشان كده اسمها dedicated يعني انا بـ dedicate الـ processor.
للـ program. معاه لحد ما يخلص. التلات طرق اللي فاتوا كان فيهم assumption ان عدد الـ threads ثابت ومعروف من الأول. بتاع كل برنامج معروف من الأول وثابت ما بيتغيرش. الطريقة الرابعة اسمها dynamic assignment يعني.
عدد الـ threads اللي  within البرنامج الواحد بيختلف أثناء الـ execution time، يعني البرنامج نفسه ممكن وهو شغال يفتح threads ويقفل threads، يفتح threads ويقفل، فالعدد يزيد ويقل يزيد ويقل، العدد مش ثابت من الأول. بس في فرق ما بين.
معروفين من بداية البرنامج وما بيتغيروش وفي فرق ان انت البرنامج اثناء ما هو شغال اللي حضر منكم المعمل الاسبوع اللي فات أو اللي قبله احنا كنا بنـ create threads في runtime. بزرار الـ start. انت ما تعرفهوش من الأول. وفي النص في حاجات بتخلص وحاجات بتكمل.
فهنا العدد ايه dynamic. هو ده اصلا الأقرب للواقع اللي هو الـ dynamic scheduling. بس ده الأسهل على الـ OS. ليه بقى؟ الأسهل من ناحية الـ scheduling يعني، هو الـ OS بيريح دماغه في الموضوع ده، انا مليش علاقة أنت عندك كام thread.
أنا هدي لك الـ processors كلها أو أو أو أنت اطلب مني، قول لي أنت عايز كام processor أنا هديهم لك. لو متاحين، هديهم لك، أنت اتصرف، أنت كبرنامج أو كـ library اتصرف، وزع الـ threads بتاعتك.
على الـ processors. يبقى عملية الـ scheduling نفسها ما بقتش مسؤولية الـ OS. الـ OS بقى في الجزء الرابع بس الـ OS مسؤوليته فقط الـ assignment، يعني أنا هدي لك العدد ده من الـ processors مدة معينة أو لحد ما تخلص.
أنت اتصرف، أنت البرنامج هو اللي يتصرف. فده الأسهل على الـ OS، خلاص؟ احنا هنتكلم بقى على أول نوعين أو تلاتة على حسب الوقت. الطريقة الأولانية اسمها الـ load sharing. هنا لو تلاحظوا بقى الـ queue ما بقاش فيه processes بقى فيه thread، يعني process 1 thread 1، process 1 thread 2. بنـ schedule على مستوى الـ threads مش على مستوى الـ.
load share simple خالص. زي ما كنت بتعمل على مستوى الـ processes، تعملها على مستوى الـ threads. فكل processor أما يبقى متاح يسحب thread. processor خلص، يسحب الـ next thread. وهكذا.
ميزة ده إن الـ processors هي اللي بتسحب ففي نوع من الـ load balancing، يعني الـ processor أما بيبقى فاضي هو اللي بيخش ويسحب. فبوزع الـ load على الـ processors. الميزة التانية.
ما فيش centralized scheduler. مين اللي بيسحب؟ ده ده أقرب لإيه؟ ده اتكلمنا عنه قبل الـ break كان اسمه إيه؟ ده peer-to-peer مش master-slave. لإن اللي بيسحب هنا هو مين؟ الـ CPU نفسه. وبالتالي.
تقدر تشغل أي بقى policy من من من الـ scheduling، ما هو ده queue في الآخر. عايز تشغله first come شغله، عايز تشغله shortest remaining شغله، عايز تشغله round robin شغله، براحتك. ما هو queue في الآخر وشغاله زي ما هي هي typical اللي كان بيحصل على الـ single بس بقى على مستوى إيه.
كذا processor وكذا thread. وفي الغالب ده يعتبر الـ most commonly used في معظم الـ operating systems. بالطريقة دي لسهولتها والمزايا اللي فيها. طيب عيبها الأساسي.
ده ايه queue ده shared فلازم يتحمي. ونتيجة إنك هتحميه بـ critical section ده ممكن يحصل عليها bottleneck. رغم إن الـ peer-to-peer كانت ميزته إن ما فيش bottleneck.
بس الـ queue ده shared، ما ينفعش اتنين يسحبوا في نفس الوقت. فلو عندك آلاف الـ processors كلهم عايزين يسحبوا هيضطروا يستنوا، يقفوا في طابور، يحصل bottleneck. وطبعا بتخسر caching، لإن أنت بتـ schedule مش دايما كل ما هتخرج وترجع.
هترجع، ما ده يعتبر dynamic assignment يعني. مش بتخرج وترجع لنفس الـ processor. الحاجة الأخيرة، ما فيش gang. ما فيش group scheduling. فده لو على مستوى بقى الـ medium-grained مش هيبقى كويس. ما فيش أي ضمانات هنا إن اللي مرتبطين ببعض.
هيشتغلوا مع بعض. وده في الغالب لو أنت ما عرفتش تشغلهم مع بعض ده ممكن يديك worse performance رغم إن أنت بتشغلهم parallel. عمال بتسحب وبتـ utilize بس نتيجة إن أنت مش مشغل كل اللي عايزين اللي عايزين بعض مع بعض.
بيحصل drop في الـ performance بتاعها. نتيجة إن الـ switching، أنا بعطل، بشتغل مثلا 20 100 instruction وبعطل. عايز إيه؟ عايز حد من اللي بره. فاضطريت أنا أخرج عشان هو يخش. يجي هو يخش، يشتغل شوية، عايز.
أو عايز حد تاني، يضطر يخرج وهكذا. طيب تعالوا نـ trace. هنا بقى الفرق هنا ما بين الـ givens هنا بقى كل برنامج.
ليه الـ threads الخاصة بيه. كل thread طبعًا ليه service time. وطبعا مدينا هنا الـ arrival عادي بتاع البرنامج على بعضه يعني. خلاص؟ بيقول عندنا أربعة processors. first come first serve. time now.
zero وعايز يحسب الـ finish time. هي مباشرة جدًا زيها زي الـ single processor يعني، شغالين first come first serve. عند، وكل الـ time now كلهم متاحين عند time 0. عند time.
0 مين وصل؟ B1. B1 وصلت، عايزة thread 1 عايز خمسة و thread 2 عايز تلاتة. حد وصل غيرها؟ خلاص. كل processor هيـ schedule الـ threads بالترتيب. يبقى ده هياخد.
process 1 thread 1 هيشتغل قد إيه ده؟ الخمسة، ليه؟ non-preemptive. والتاني هياخد من 0 ل3  اللي هي process 1 thread 2.
next. عند time تلاتة B2 وصلت وليها تلاتة threads. thread 1 و 2 و 3 عايزين اتنين وواحد وأربعة. عند time تلاتة في تلاتة فاضيين.
خلاص؟ كل واحد هيـ schedule الـ thread بالترتيب. ده هياخد process 2 thread 1، دي عايزة اتنين تشتغل من تلاتة لخمسة process 2 thread 1. دي هتاخد من تلاتة لأربعة.
process 2 thread 2 ودي هتاخد من 3 ل 7 بظبط process 2 thread 3 وكده دول كل دول خلصوا
طيب عند time خمسة B3 وصلت عايزة أربعة threads. وبرضه عند time خمسة.
B4 وصلت وعايزة two threads. ونحط الـ timing. فأنت عند time خمسة.
عند time خمسة التلاتة أول تلاتة processors فاضيين. كل processor هيخش يسحب الـ next thread بالترتيب اللي هما فيه دول، خلاص؟ فده هيسحب B3 thread 1.
من خمسة لستة. ده هيسحب من خمسة لسبعة. B3 thread 2. وده برضه من خمسة لسبعة.
B3 thread 3. وده لسه مشغول. فين أول واحد فضي؟ ستة فضي، يروح ساحب الـ next thread اللي عليه الدور، مين اللي عليه الدور دلوقتي؟ ده خلص وده خلص وده خلص.
B3 thread 4. عايز تلاتة يبقى من ستة لتسعة. B3 thread 4. وهكذا. next. التلاتة processors دول فضيوا.
عندنا B4 thread 1 عايز سبعة. هاخد من 7 لـ 14. B4 thread 1. وده هياخد من 7 لـ 10.
خلاص؟ هنا بقى عشان بس يبان الفرق. لو افترضنا إن الأربعة threads بتوع B3 كانوا محتاجين بعض.
هل هما اشتغلوا مع بعض؟ لأ. ما اشتغلوش، فعشان كده بنقول ده ما بيخدمش الـ gang أو الـ group scheduling يعني. عكسه بقى الـ group scheduling. إن الحاجات الـ related ببعض لازم يحصلها scheduling.
مع بعض. فمثلًا لو افترضنا إن كل شوية threads في الـ process related ببعض فلازم يخشوا مع بعض، طب لو ما عنديش processors تكفي؟ يستنوا، يستنوا كلهم، ما حدش بيشتغل.
فبيخشوا مع بعض، يخرجوا مع بعض. خلاص؟ طبعا ميزة ده، حاضر، ميزة ده إن هو بيخدم جدًا ال granularities  العالية اللي هي ال medium وال fine-grain اللي بيحتاجوا بعض كتير أشغلهم مع بعض فأضمن إن هما يلاقوا بعض.
ميزة إن هما أما يلاقوا بعض إن محدش هيعطل على التاني. فالـ context switching قليل. الـ blocking إن أنا أبلوك عشان مستني dependencies قليل، ما هو التاني شغال معايا. وأحيانًا كتير بيبقى الـ busy waiting هنا.
أفضل من الـ sleep. ما هما شغالين مع بعض. فأنا حتى لو هـ busy wait، هـ busy wait والتاني موجود معايا، فأنا مش هستنى كتير. لإن أنا ضامن إن التاني شغال معايا. أحسن لي من لو كنت إيه.
أsleep، أَblook، أضطر أsave الstatus كلها وأنام وبعدين حد يجي يفوقني أضطر أload وأخسر الcache ساعتها بتاعتي. فساعاتهنا يكون الـ Busy Waiting أفضل من الـ Sleep.
لا لا ما أنت بتدخلهم مع بعض وتديهم time slice زي الـ round robin كده هنشوف حالًا. فعلى حسب ما بيخلصوا. خلصوا خلصوا، ما خلصوش، وقتهم خلص، كله يخرج ويخشوا تاني.
بتديلهم كلهم بس هما أوقاتهم مختلفة. ممكن thread يخلص وthread تاني لأ. مش هما كلهم بيخشوا، كلهم يخرجوا. أنا عارف إن مثلًا... آه لا لا لا هما طبعا الـ dependencies هنا على مستوى الـ process نفسها.
الـ threads اللي within الـ process. آه بس لازم أبقى عارف. فيا إما بتبقى declared مسبقًا من البرنامج يا إما أنا بشتغل على الـ threads بتاعت البرنامج كلها. بس فرقها عن الـ dedicated إن أنا بدخلهم مش preemptive مش non-preemptive.
الطريقة دي ما ينفعش تطبقها لو هو مثلًا عنده خمسة threads وهما أربعة processors. آه طبعا، ما ينفعش يبقى عدد الـ threads الـ related أكبر من عدد الـ processors. طب ساعتها يعمل إيه؟ يجبر البرنامج إنه يقلل الـ relations اللي ما بين يكسر فبرضه ديها limitations.
ماشى طيب. ميزتها طبعا الـ gang scheduling إن هو بيقلل الـ context switching وبيقلل الـ concurrency overhead أو الـ locking إن أنا أضطر أعطل عشان حد يشغلني، ما أنا كده كده هو شغال معايا حتى لو عطلت.
اللي بنسميها synchronization blocking يعني، مش بعطل كتير لإن التاني شغال معايا في نفس الوقت. وهنا في concept يعني بيسموها الـ activity working set، فاكرين working set دي؟ إيه الـ working set؟ أقل عدد pages محتاجها دلوقتي عشان أعرف أشتغل من غير.
فيحصل لي thrashing. نفس الـ concept ده مطبق على الـ processors. إيه أقل عدد processors أنت محتاجه دلوقتي عشان الـ threads بتاعتك تشتغل مع بعض من غير ما يحتاجوا thrashing. من غير ما يحتاجوا يخرجوا ويستنوا على بعض.
يعني أنا دلوقتي محتاج تلاتة threads مع بعض يبقى تديني كام processor؟ تلاتة. فنفس المعنى يعني، نفس ونفس المشكلة اللي كانت حاصلة هناك هتحصل هنا لو أنت اديته أقل من العدد اللي هو عايزه. واصلة الفكرة؟ طيب. اللي هو ممكن تؤدي إلى.
thrashing لو ما عرفتش أديله. طيب نيجي لشكل الـ gang scheduling. احنا قلنا إن أنت بتوزع preemptive. عندك طريقتين هنا، يا إما توزع uniform.
يعني إيه؟ كل برنامج هياخد time slice على حسب مدتها قد إيه يعني، بس اللي بنسميها quantum يعني. كل برنامج هياخد الـ processors كلها مدة زمنية معينة.
خلص خلص، ما خلصش هخرجه وأدي الـ processors كلها لبرنامج تاني. نفس الفكرة، ما خلصش خرج وأدي للتالت، يعني بـ round robin على الـ processors كلها، الـ processes كلها. ده اسمه uniform.