بخشی از مقاله
چکیده: چندین سال است که برنامهنویسی موازی به عنوان یک زمینه پژوهشی در علوم کامپیوتر و مهندسی نرمافزار فعال است. در حالت ایدهآل، برنامهنویسی موازی باید در مسائل محاسباتی افزایش سرعت خطی را فراهم کند. اما در واقع این افزایش سرعت به ندرت اتفاق میافتد. در حالی که الگوریتمهایی وجود دارند که نمیتوانند به حالت موازی نوشته شوند، اما آنهایی که به حالت موازی تبدیل میشوند نیز همچنان قادر به افزایش سرعت خطی مطلوب نیستند. نوشتن یک کد موازی برای الگوریتمهایی که میتوانند به این صورت نوشته شوند معمولا بسیار سختتر از نوشتن یک برنامه ترتیبی و یک نخی است.
وجود این شکاف بین محاسبات موازی ایدهآل و محاسبات موازی بر روی سختافزار و نرمافزار واقعی باعث شده است بسیاری از توسعهدهندگان به دنبال ایجاد راه حلهای جدیدی برای حرکت محاسبات موازی واقعی به سمت مدل ایدهآل آنها باشند. درحالی که بسیاری از این راهکارها مزایای عملکردی عالی را در سیستمهای بزرگ ارائه میدهند، اما در هنگام استفاده از سیستمهای کوچک نمیتوانند به خوبی عمل کنند. در این مقاله، یک میانافزار مبتنی بر پایتون طراحی شده است که برای نوشتن برنامههای کاربردی پردازش موازی جهت اجرا بر روی خوشههای کامپیوترهای کوچک به کار میرود. نتایج ارزیابی امکانپذیری این میان افزار را نشان میدهد.
.1 مقدمه1
بسیاری از کارهای در حال انجام توسط کامپیوترهای امروزه قابل موازی سازی هستند. با این وجود، افزایش عملکرد حاصل از اجرای کارها به صورت موازی فاصله زیادی با افزایش سرعت خطی مورد انتظار داشته و حتی در بعضی موارد، در مقایسه با اجرای آن کار به صورت یک برنامه ترتیبی یک نخی نتیجه عملکرد پایین تری به دست می آید. در حال حاضر چارچوب های زیادی برای توسعه برنامه های کاربردی موازی و توزیع شده وجود دارند و هر چارچوب موازی سازی را به روش خاص خود انجام می دهد. در نتیجه با استفاده از چارچوب های مختلف، برنامه های موازی مختلف در تنظیمات سخت افزاری متفاوت قرار می گیرند. ما در این مقاله، طراحی، پیاده سازی و ارزیابی یک میان افزار برای محاسبات توزیع شده را ارائه می دهیم و عملکرد موازی سازی آن را به دیگر چارچوب های محاسبات توزیع شده رایج مقایسه می کنیم.
در طی چند سال گذشته، چندین میان افزار و کتابخانه مختلف برای محاسبات موازی توسعه یافته اند. ما در این مقاله پارادایم های برنامه نویسی موازی و کارهای مرتبط را به دسته های زیر طبقه بندی کرده ایم: انتقال پیام - message passing - ، برنامه نویسی جریان داده ها - dataflow - programming، فراخوانی رویه راه دور - remote procedure call - و شی راه دور . - remote objects - انتقال پیام: انتقال پیام سطح پایین ترین و کم انتزاع ترین روش اجرای برنامه های موازی است. یک چارچوب پیاده سازی انتقال پیام به یک برنامه نویس امکان می دهد که فرایندها بتوانند ارسال و دریافت پیام را در هر لحظه از لحاظ و به صورت نقطه به نقطه و یا پخشی انجام دهند.
بزرگترین محدودیت پارادایم انتقال پیام عدم انتزاع آن است. برای اکثر برنامه های موازی توزیع شده، استفاده از پارادایم انتقال پیام مشکل تر از استفاده از پارادایم هایی مثل فراخوانی رویه راه دور و یا شی راه دور است. اندازه گیری سربار مرتبط با برنامه پیاده سازی شده به روش انتقال پیام دشوار است، زیرا طراحی بخش های زیادی از موازی سازی بر عهده توسعه دهنده قرار می گیرد و مقدار بسیار کمی از آن را خود چارچوب انجام می دهد. برای پیاده سازی الگوریتم های موازی با پارادایم انتقال پیام در پایتون می توان از استاندارد رابط انتقال پیام - MPI - تحت عنوان [1] Mpi4py استفاده کرد.
برنامه نویسی جریان داده: برنامه نویسی جریان داده ها نسبت به رویکرد سنتی دستور محور در طراحی برنامه متفاوت است و به جای آن بر روی پردازش جریان داده ها تمرکز می کند. مزیت عمده این پارادایم این است که برنامه هایی که توسط برنامه نویسی جریان داده ها پیاده سازی می شوند به صورت ذاتی موازی هستند .[2] با توجه به ماهیت موازی سازی ذاتی برنامه نویسی جریان داده ها، برنامه نویس تاثیر کمی در طراحی موازی برنامه دارد. بنابراین چارچوب برنامه نویسی موازی مسئولیت بهینه سازی برنامه توزیع شده است. در حالی که اجرای وظایف پردازش داده ها به صورت همزمان می تواند مشابه استفاده بهینه از سیستم کامپیوتر توزیع شده به نظر آید، اما باید به هزینه بالای انتقال اطلاعات بین کامپیوترهای موجود در سیستم توزیع شده نیز توجه شود.
این همان نکته ای است که باعث می شود سیستم های موازی توزیع شده، مجموعه کارها را کندتر از یک سیستم تک نخی اجرا کنند. این سربار وابستگی زیادی به عملکرد شبکه اتصال دهنده کامپیوترها در سیستم توزیع شده دارد. همچنین سرعت خواندن/نوشتن سیستم فایل می تواند نقش موثری در کارایی موازی سازی یک نرم افزار ایفا کند. Apache Pig .[3] یک زبان برنامه نویسی جریان داده است که برای کار در خوشه ای از کامپیوترهای محاسبات موازی که Apache Hadoop را اجرا می کنند طراحی شده است .[4] این پارادایم هنوز پشتیبانی کمی در زبان پایتون دارد .[5]
فراخوانی رویه راه دور: پارادایم RPC نسبت به پارادایم انتقال پیام، انتزاع بسیار بالاتری را به یک برنامه نویس ارائه می دهد. با توجه به ماهیت فراخوانی یک متد از یک فرایند در فرایند دیگر، معمولا برنامه های مبتنی بر RPC به صورت master-slave هستند .[6] فرایند فراخوانی کننده درون خود یک stub دارد که به متد راه دور مرتبط می شود. فرایند فراخوانی کننده این stub را مشابه فراخوانی یک متد محلی فراخوانی می کند. چارچوب RPC جزئیات تنظیم کانال ارتباطی با فرایند راه دور، فراخوانی متد راه دور و بازگرداندن نتایج محاسبات در صورت وجود را انجام می دهد.
چارچوب های برنامه نویسی موازی مبتنی بر RPC، سطوحی از انتزاع را برای توسعه دهندگان فراهم می کند و بنابراین مسئولیت تولید موازی سازی کارا بین توسعه دهنده نرم افزار موازی و توسعه دهنده چارچوب برنامه نویسی موازی تسهیم می شود. هنگامی که یک فراخوانی راه دور اتفاق می افتد، تمام داده هایی که به متد راه دور منتقل می شود باید سریال شده، از طریق شبکه منتقل و قبل از فراخوانی آن متد از حالت سریال خارج شوند.
به طور مشابه، هنگامی که کار متد راه دور به پایان می رسد، باید تمام داده های بازگشتی سریال شده، از طریق شبکه منتقل و قبل از بازگشت به متد فراخواننده از حالت سریال خارج شوند. این سربار باعث می شود که عملکرد نرم افزارهای موازی و توزیع شده کمتر از مدل ایده آل - افزایش سرعت خطی - باشد و در صورت فراخوانی مکرر فرایندهای راه دور و با مقدار زیاد داده ها، می تواند موجب کاهش شدید عملکرد شود. در پایتون فراخوانی رویه ای راه دور را می توان با کتابخانه Parallel Python انجام داد .[7]
شی راه دور: شی راه دور ایده خود را از RPC گرفته و آن را به کل اشیاء و نه فقط متدها گسترش می دهد. شی راه دور در مورد توجه برنامه های وب هستند. به عنوان مثال، پروتکل دسترسی ساده شی - SOAP - یک پروتکل توصیه شده W3C است که برای تعامل شی راه دور در برنامه های وب استفاده می شود .[8] سربار مرتبط با چارچوب های شی راه دور همانند فراخوانی راه دور است. در پایتون می توان از کتابخانه Python [9] Remote Objects - PyRO - برای این پارادایم استفاده کرد.
به منظور کاهش سربار مرتبط با رویکردهای مختلف برنامه نویسی موازی و توزیع شده، تکنیک های مختلفی پیشنهاد شده است. در سیستم های محاسباتی توزیع شده که مقدار زیادی داده برای پخش در تمام گره های یک خوشه وجود دارد، برای ارسال داده ها به تمام گره ها در زمان تقریبا ثابت بر روی روش های سخت افزاری تمرکز شده است .[10] Apache Hadoop برای پردازش مجموعه داده های زیادی در سیستم های توزیع شده با درجه بالای مقیاس پذیری طراحی شده است. این مجموعه داده های بزرگ در سیستم فایل توزیع Hadoop - HDFS - ذخیره می شود. زمانی که یک برنامه کاربردی از HDFS استفاده می کند، مانند چارچوب MapReduce، هنگامی که یک کار را زمانبدی کند، زمانبند سعی می کند آن کار را در همان گره ای انجام دهد که داده های مورد نیاز را درون خود دارد و بنابراین امکان کاهش سربار ارتباطات به حداقل می رسد .[11]
.2 طراحی میان افزار
این میان افزار به عنوان یک میان افزار تدارکاتی طراحی شده است و با ارائه روش های مختلف اجرای کار، امکان موازی سازی را به وجود می آورد. علاوه بر این، این ابزار از معماری master-slave پیروی می کند که در آن فرایند master ، کار را برای فرایندهای slave می سپارد. همچنین این ابزار روش هایی را برای انتقال اشیاء داده بزرگ بین گره های خوشه فراهم می کند. روش های انجام کار در ادامه توضیح داده شده اند: روش کار ترتیبی یا :Sequential Task این روش کار را به گونه ای اجرا می کند که به نظر می رسد این کار بخشی از یک برنامه متوالی عادی بوده است. این فراخوانی تابع تا زمانی که فرایند راه دور داده ها را بازنگرداند، مسدود می شود. داده های نتیجه بازگردانده شده به تابع فراخواننده بازگردانده می شوند.
روش کار موازی یا :Concurrent Task این روش کار را به صورت ناهمزمان - asynchronously - انجام داده و فرایند را متوقف نمی کند. این روش، کار را بر روی یک نخ دیگر در یکی از گره های خوشه شروع می کند و نتیجه آن شی کنترل کننده آن فرایند خواهد بود. سپس این شی می تواند برای توقف برنامه master تا پایان کار دوم و همچنین بازیابی نتایج آن استفاده شود. روش کار طولانی یا :Long Task این روش برای الگوریتم های زنجیره ای طولانی مفید است.
این روش یک کار را شروع کرده و به برنامه master اجازه می دهد که آن را به پایان رساند. همچنین یک برنامه نویس می تواند این کار را به یک گروه از گره های worker متصل کند تا هر زمان که یک worker نتیجه را به دست آورد، سایر workerها کار را متوقف کنند. گره master برای اتصال کار به یک گروه از workerها باید یک MasterServer را اجرا کند. وظیفه این سرور این است که گروه های LongTask را کنترل کرده و اطلاعات وضعیت آن ها را ارائه کند. هنگامی که یک worker نتیجه را به دست آورد، MasterServer را مطلع می کند. فرایند اصلی میتواند یک متد wait را در MasterServer فراخوانی کند که تا زمان تهیه نتیجه توسط یک worker، این سرور را متوقف خواهد کرد.
روش پخش کار یا :Broadcast Task در این روش یک متد به صورت یکپارچه در تمام گره های خوشه اجرا می شود. در ادامه یک لیست از اشیاء برمی گردد که نشان دهنده روند فراخوانی در هر گره است. سپس این لیست می تواند برای انتظار تا پایان کار فرایندها و پس از آن تهیه خروجی حاصل به کار رود. در ادامه متدهایی توضیح داده شده اند که برای انتقال کارای داده های بزرگ توسط این میان افزار استفاده می شوند.
روش کارهای موازی بر روی فایل ها: این روش همانند روش کار موازی در میان افزار، امکان اشتراک گذاری یک فایل را با گره ای که برای اجرای متد انتخاب می شود فراهم می آورد. فرایند master در زمان فراخوانی فرایند راه دور، نام فایلی را که قرار است محتوای آن ارسال شود مشخص کرده و میان افزار مراحل کپی فایل از گره master به گره راه دور را انجام می دهد. روش VariableServerها و VariableClientها: هنگامی که اندازه شی پایتون که قرار است ارسال شود بزرگ باشد، استفاده از روش های فراخوانی راه دور و یا شی راه دور می تواند کارایی کمی داشته باشد.
میان افزار این مشکل را به این صورت حل می کند که یک سرور با کارایی بالا را برای انجام عمل انتقال اشیاء بزرگ در نظر می گیرد و در همین زمان متد راه دور یا شی راه دور به راحتی با ارسال و دریافت لینک کوچک به اطلاعات مورد نظر کار خود را آغاز می کند. هنگامی که یک فرایند می خواهد یک شی بزرگ ارسال کند، یک VariableServer ایجاد کرده و شی بزرگ را به آن متصل می کند. فرایندی که قرار است یک شی بزرگ دریافت کند یک VariableClient ایجاد کرده و از لینک دریافت شده از طریق فراخوانی راه دور برای دانلود داده های بزرگ شی استفاده می کند.
.3 پیاده سازی میان افزار
ما برای اثبات کارایی این میان افزار، با استفاده از [9] Python Reomote Objects - PyRO - یک پیاده سازی برای ارتباط بین فرایندهای درون یک خوشه ساخته ایم. ما به علت سادگی رابط کاربری برنامه نویسی و مستندات مناسب این کتابخانه از آن برای نمونه سازی اولیه استفاده کرده ایم. در زبان برنامه نویسی پایتون، همه چیز در غالب شی تعریف می شود.