چگونه برنامه نویسی موازی را برای مادربزرگتان توضیح دهید؟

ترجمه و تالیف : فاطمه شیرزادفر
تاریخ انتشار : 09 اردیبهشت 99
خواندن در 4 دقیقه
دسته بندی ها : برنامه نویسی

در دنیای برنامه نویسی، عمدتا برنامه نویسی موازی به multi-theading یا چند نخی ترجمه می‌شود. Thread یا همان نخ یک مفهوم انتزاعی است که می‌توانیم آن را مانند یک کارگر که وظایف خود را درون یک کامپیوتر انجام می‌دهد، تصور کنیم. به‌عنوان مثال اگر می‌خواهید متدی مثل (Add(2,3 را اجرا کنید، می‌توانید آن را به یک نخ اختصاص دهید و منتظر نتیجه آن باشید. نخ‌ها مفاهیمی هستند که وظیفه انجام کارها روی cpu را دارند.

بنابراین،‌ نخ‌ها شبیه به انسان‌ها هستند؛ آن‌ها می‌توانند کارها را با استفاده از منابع موجود مانند cpu,memory ,network و … انجام دهند، درست مثل انسان‌ها که با استفاده از مغز و حافظه و … کارهایشان را انجام می‌دهند.

برای ساده‌تر کردن این مفاهیم،‌ قصد دارم به جای استفاده از مفهوم نخ، از انسان‌‌ها برای مدل پردازش موازی استفاده کنم.

در این مقاله دو مفهوم را از هم جدا می‌کنم: موازی‌سازی ( Parallelism )‌ و ناهمگام‌سازی (Asynchrony ).

برنامه نویسی موازی ( PARALLEL PROGRAMMING )

تصور کنید در یک فروشگاه مواد غذایی با یک لیست در دستانتان هستید. شما باید تمام آن ۵۰ مورد، که در لیست نوشته شده را به تنهایی پیدا کنید و درون سبد قرار دهید.

راه‌حل متوالی

یک راه‌حل متوالی این است که تمام آن موارد را به تنهایی پیدا کنید. پس الگوریتم این خواهد بود :

چگونه برنامه نویسی موازی را برای مادربزرگتان توضیح دهید؟

راه‌حل موازی

حالا در نظر بگیرید که تنها نیستید، شما با ۱۰ نفر از دوستانتان به فروشگاه رفته‌اید و قصد دارید تا وسایلی را که نیاز دارید، جمع کنید. شما می‌توانید لیست خود را به ۱۰ ساب لیست تقسیم کنید و هر یک را به یکی از دوستان خود اختصاص دهید. بنابراین راه‌حل موازی این خواهد بود :

چگونه برنامه نویسی موازی را برای مادربزرگتان توضیح دهید؟

اما اگر جمع‌آوری لیست‌ها برای جیم و جین راحت‌تر باشد، چه می‌شود؟ به عنوام مثال ساب لیست‌ جیم، شامل میوه‌هایی است که همه‌ی آن‌ها در قسمت میوه موجود است و جمع آوری آن فقط ۱ دقیقه طول می‌کشد؛ در عین حال جمع‌آوری بعضی از لیست‌ها سخت‌تر است، به عنوان مثال ساب لیست مهران شامل موارد زیر است : 

سیب

کفش

توپ

شامپو

قند

مهران بیچاره ! اگرچه لیست او نیز مشابه دیگران فقط ۵ مورد دارد، اما لیست او واقعاً سخت‌تر است؛ زیرا کالا‌های او در سراسر فروشگاه پخش شده. همان‌طور که گفته شد،‌ با استفاده از الگوریتم موازی‌سازی بعد از ۳ دقیقه همه‌ی افراد کار خود را تمام می‌کنند؛ به جز مهران! افراد دیگر منتظر او هستند تا کارش را تمام کند، و بدتر از آن اینکه، آن‌ها حتی با وجود اینکه قادر به کمک کردن به او هستند، این کار را نمی‌کنند.

راه‌حل بهتر برای موازی‌سازی

مشکل راه‌حل قبلی چیست؟ اگرچه اندازه لیست‌ها ثابت و یکسان است (‌۵ مورد برای همه‌ی افراد‌) اما پیدا کردن موارد مختلف، زمان‌های مختلفی را می‌طلبد؛ چرا که در مکان‌های مختلفی از فروشگاه قرار دارند. اگر زمان لازم برای یافتن هر مورد را می‌دانستیم، می‌توانستیم ساب لیست‌های هوشمندانه تری بنویسیم. به طور مثال اگر پیدا کردن توپ ۵ دقیقه و سیب‌زمینی ۱ دقیقه طول می‌کشد، می‌توانستیم آن‌ها را در یک لیست قرار دهیم و در آخر همه‌ی لیست‌ها را بالانس کنیم. اما متأسفانه ما درباره میزان زمان لازم برای یافتن هر مورد، هنگام ورود به فروشگاه اطلاعاتی نداریم.

از آنجا که پیدا کردن یک راه‌حل بهینه‌تر موضوع این مقاله نیست، من نمی‌خواهم در این باره بحث کنم؛ اما می‌توانید خودتان را به چالش بکشید و از خلاقیتتان برای یافتن یک راه‌حل مناسب استفاده کنید.(راه‌حل‌های خودتون رو در قسمت نظرات با ما به اشتراک بگذارید.)

برنامه نویسی ناهمگام ( ASYNCHRONOUS PROGRAMMING )

انجام برخی کارها به طور غیر همزمان یا ناهمگام،‌ دقیقا برابر با انجام دادن آن‌ها به طور موازی نیست، در حقیقت موازی‌سازی یکی از راه‌حل‌های دستیابی به asynchrony است. یک راه‌حل گران!

  • برنامه نویسی موازی یک راه‌حل گران برای دستیابی به برنامه نویسی Asynchronous است.

برای توصیف برنامه نویسی asynchronous و ارتباط آن با برنامه نویسی موازی، مصاحبهEric Lippert  را بسیار جالب دیدم (‌گفتگوی کامل را می‌توانید در اینجا پیدا کنید.)

بنابراین بخشی از آن را برایتان انتخاب کردم و در اینجا آورده‌ام :

  • یک قیاس ممکن است کمک کند. فرض کنید در آشپزخانه یک رستوارن هستید، دوسفارش وارد می‌شود، یکی برای نان تست و دیگری تخم‌مرغ.

یک گردش کار synchronous اینگونه خواهد بود : نان تست را داخل تستر بگذارید، صبر کنید تا آماده شود و آن‌ها را تحویل دهید، تخم‌مرغ‌ها را درون ماهی‌تابه بیندازید، صبر کنید تا پخته شوند و سپس آن‌ها را تحویل دهید. کارگر یا همان (شما) هنگامی‌که منتظر هستید، کاری انجام نمی‌دهید به جز آنکه بشینید و منتظر بمانید.

یک گردش کار Asynchronous اما غیر موازی اینگونه خواهد بود : نان را داخل توستر بگذارید، در حالی‌که نان درحال تست شدن است تخم‌مرغ‌ها را درون ماهی‌تابه بیندازید؛ و گزینه‌ی دیگر بررسی تخم‌مرغ‌ها، چک کردن نان تست و بررسی اینکه آیا سفارش جدیدی وجود دارد یا نه – هرکدام از این‌ها ابتدا انجام می‌شود،‌ ابتدا تحویل بگیرید، سپس منتظر بمانید تا دیگری به پایان برسد، و دوباره؛ دائماً هم بررسی کنید تا ببینید که سفارش جدیدی وجود دارد یا نه.

یک گردش کار موازی وAsynchronous اینگونه خواهد بود : شما فقط در آنجا نشسته‌اید و منتظر سفارش‌ها هستید؛ هربار که یک سفارش جدید وارد آشپزخانه می‌شود آن را به یک آشپز می‌دهید تا او شروع به آماده کردن سفارش کند. بنابراین یک آشپز تخم‌مرغ‌ها را آماده می‌کند و آشپز دیگری نان تست را آماده می‌‌کند و درحالی که آن‌ها در حال پخت‌وپز هستند، شما هم همچنان سفارش‌های بیشتری دریافت می‌کنید. سپس سفارش را تحویل داده و کار آشپز تمام می‌شود.

توجه کنید که ساز و کار دوم،‌ انتخاب یک رستوران واقعی خواهد بود؛ چراکه ترکیبی از هزینه‌ی کم‌تر (آشپز گران است!‌) با پاسخ‌گویی و توان بالاست. روش اول قدرت و پاسخ‌گویی ضعیفی دارد و روش سوم نیاز به پرداخت مقدار زیادی پول به آشپز را دارد تا زمانی که آن را نیاز دارید از آن استفاده کنید.

در مصاحبه Eric Lippert ،‌ نقل قول خوبی هست که می‌گوید :

موازی‌سازی یک تکنیک برای دستیابی به asynchrony است اما asynchrony لزوماً به معنای موازی بودن نیست. - اریک لیپرت -

مقایسه‌یParallel (موازی‌سازی) و Asynchronous (غیرهمگام)

اکثر اوقات که می‌خواهم از thread (نخ)‌ها در یک قطعه کد استفاده کنم، از خودم می‌پرسم که چه نوع مشکلی را می‌خواهم حل کنم؟ آیا من برای پیاده‌سازی برنامه نویسی موازی از نخ‌ها استفاده می‌کنم یا بیشتر برای پیاده‌سازی یک وضعیت Asynchronous ؟ باور کنید این دو کاملاً متفاوت هستند!!

وقتی می‌خواهید از برنامه نویسی موازی استفاده کنید،‌ می‌‌خواهید از حداکثر نخ‌هایی که می‌توانید، استفاده کنید. شما الگوریتم ها را بهینه‌ می‌کنید تا برنامه‌ بتواند از نخ‌های بیشتر و بیشتری استفاده کند.

اما وقتی می‌خواهید از برنامه نویسی Asynchronous استفاده کنید، برعکس است! شما می‌خواهید برای کارهای خود از حداقل نخ‌ها استفاده کنید. راه‌حل مطلوب، استفاده از نخ برای انجام همه‌ی کارها به صورتAsynchronous است.

بنابراین، پیشنهاد می‌کنم اگر می‌خواهید هر کدی را بنویسید که حاوی مفهوم موازی باشد، این را به خاطر بسپارید :

برنامه نویسی موازی، استفاده از نخ‌های بیشتر و بیشتر به طور مؤثر است.

برنامه‌نویسی Asynchronous ، استفاده از نخ‌ها به صورت حداقلی و مؤثر است.

منبع

گردآوری و تالیف فاطمه شیرزادفر
آفلاین
user-avatar

تجربه کلمه‌ای هست که همه برای توصیف اشتباهاتشون ازش استفاده میکنن، و من همیشه دنبال اشتباهات جدیدم! برنامه‌نویس هستم و لینوکس‌ دوست

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر لازم است ابتدا وارد سایت شوید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید