انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید

نویسنده موضوع: اجرای دستور پایتون در شل های مختلف به صورت موازی  (دفعات بازدید: 2075 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین Fire.Phoenix

  • Full Member
  • *
  • ارسال: 108
سلام
کدی دارم به شکل زیر
a = input
for b in a :
do something with b
pass
اون ورودی یک فایل است با چیزی بیش از دو هزار ورودی،پردازش هر ورودی هم ۱۵ ثانیه طول میکشه
دنبال راهی بودم به که به پایتون بگم هر ۵ تا ورودی را توی یک شل جدید به یک for بده و بعد ۴۰۰ تا for را با هم اجرا کن
اینگونه در ۷۵ ثانیه کل دستورات اجرا بشود

آفلاین ارباب!

  • Sr. Member
  • *
  • ارسال: 448
  • جنسیت : پسر
سلام..
تا جایی که من اطلاع دارم:
شما اگه یه پردازنده ی تک هسته ای داشته باشین
تقسیم یه کد به چن کد که تقریبا هم زمان اجرا بشن مشکل خاصی رو حل نمی کنه..
چون پردازنده در هر لحظه مشغول اجرای یکی از اون کد ها هست..
فقط این دفعات switch کردن بین برنامه ها انقدر سریع هست
که شما فک می کنید دارن هم زمان اجرا می شن..
ولی اگه چند هسته یا چند پردازنده داشته باشین
multithreading و multiprocessing می تونه کمکتون کنه..
ینی هر قسمت از کد در یه هسته ی جدا اجرا بشه..
البته در پیاده سازی اصلی پایتون به نام CPython این multithreading ظاهرا یه مقدار ماجرا داره..
ینی مث این که در پیاده سازی اصلی به دلیل وجود چیزی به نام GIL
اصن thread ها هم زمان در هسته های جدا اجرا نمی شن..
یه راه حل استفاده از ماژول multiprocessing هست..
یا می تونید از پیاده سازی های دیگه ی پایتون استفاده کنید..
خوب البته به جای این که یه برنامه بنویسید و توش کد multithreading یا multiprocessing بزنید
گاهی یه راه دیگه هم مشابه اون چیزی که خواستید هست..
می تونید چن نسخه از برنامتون رو (به تعداد هسته های پردازنده..)
هر کدوم رو در هسته ای جداگانه اجرا کنید.. (نه در یک هسته..)
این طوری می تونید سرعت کار رو ببرید بالا.. (این هم یه جورایی استفاده از چند thread و چند process محسوب می شه..)
یه برنامه ای در لینوکس برای تعیین این که یه process از چه هسته هایی استفاده کنه وجود داره به اسم taskset:
http://xmodulo.com/run-program-process-specific-cpu-cores-linux.html
می خواید تست کنید ببینید می تونه با پایتون کار کنه و شما رو به هدفتون برسونه..؟
« آخرین ویرایش: 09 دی 1395، 02:49 ق‌ظ توسط ارباب! »
Void Linux + XFCE

آفلاین Fire.Phoenix

  • Full Member
  • *
  • ارسال: 108
درواقع اون کار ارسال یک سری درخواست به سایت است
که توی اسکریپت باید ۱۰ تا ۱۵ ثانیه منتظر جواب از سایت بماند
اگر بخواهم درخواست ها را تک به تک بفرستم زمانی که برنامه منتظر جواب است میخواهم درخواست های دیگه ارسال بشه
بعد هم جواب ها چنداتا پردازش روشون صورت میگیره

آفلاین علی رزم دیده

  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1244
  • جنسیت : پسر
  • ali76 سابق
سلام  :)
دوست عزیزمون توضیحات کاملی رو گفتن فقط منم اگه اجازه بدین منم یه چند مورد اضافه کنم
1.اگه برنامه ی شما اونقدر سنگینه بهتره تو زبان c++ بنویسینش چون بسته به پروسه شما c مقدار ۱۰ تا ۱۰۰ برابر سریع تر از پایتون عمل می کنه مثلا شما این دو تا کد ساده رو رو سیستم خودتون ران کنین تفاوت رو کاملا احساس می کنین (رو سیستم من پایتون 0.1 سرعت سی رو داشت)
سی :
#include <stdio.h>
#include "time.h"
int main(){
    clock_t begin = clock();
    int i;
    for (i; i<1000000 ; i++){
        printf("%d", i);
    }
clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("\n%f", time_spent);
}
پایتون :
import time
begin = time.time()
for i in range(1000000):
    print(i, end="")
end = time.time()
time_spent = end - begin
print('\n', time_spent)

2.اگه امکانش نیست نمی خوای یا حوصله اش رو نداری یا هر چی از مفسر pypy استفاده کن (البته به شرط اینکه ماژول ها و سینتکس های استفاده شده هم توی pypy پشتیبانی بشن چون بعضی از ماژول ها فعلا پشتیبانی نمی شن بعضاً تو سینتکس ها هم به مشکل می خوره) این مفسر طبق بنچمارک ها سرعتی ۱۰ برابری نسبت به cpython ارائه می کنه

نقل‌قول
اون ورودی یک فایل است با چیزی بیش از دو هزار ورودی،پردازش هر ورودی هم ۱۵ ثانیه طول میکشه
دنبال راهی بودم به که به پایتون بگم هر ۵ تا ورودی را توی یک شل جدید به یک for بده و بعد ۴۰۰ تا for را با هم اجرا کن
اینگونه در ۷۵ ثانیه کل دستورات اجرا بشود
اینکه شما می فرمایین صرفا یه محاسبه ی ذهنی هستش ولی تو عمل کاربردی نداره
اگه سی پی یو تک هسته ای باشه و یا برنامه فقط از یک هسته استفاده کنه (که معمولا این مورد اتفاق میوفته) تفاوتی نداره شما ۵ تا پروسه رو هم زمان انجام بدین یا ۵ تا پشت سر هم چون وقتی ۵ پروسه هم زمان انجام می شه در واقع به نوبت دارن رو پپردازنده اجرا می شن (مثلا به صورت انتزاعی (به لحاظ علمی غلطه !) می تونیم این درک شهودی رو داشته باشیم که ۵ نفر توی صف نونوایی هستن ولی هر کی نون گرفت می ره آخر صف  ;) عملی مشابه این هم توی پردازنده اتفاق میوفته و به نوبت پردازش می شن نه هم زمان / همون طور که توی نونوایی اگه یه نفر ۱۰۰ تا نون بگیره به لحاظ سرعت فرقی نداره با اینکه ۱۰۰ نفر بیان ۱۰۰ تا نون بگیرن و نمی تونیم بگیم اگه ۱۰۰ نفر باشن سرعت ۱۰۰ برابر می شه چون کلا یه درگاه وجود داره و سرعت اصلی به شاطر و سرعت پخت و ... بستگی داره)
ولی تو پردازنده ی چند هسته ای قضیه متفاوته و می شه که چند تا پروسه هم زمان انجام بشه ولی بقیه ی ماجرا به هنر برنامه نویس بستگی داره که بتونه برنامه ای بنویسه که از حداکثر توان پردازنده استفاده ی بهینه رو بکنه !
برای این کار باید خودتون توی دستورات برنامه اون رو به ۵ قسمت تقسیم کنین و هر قسمت رو به یک هسته محول کنین و اینکار به وسیله ی کتابخونه هایی عین multiprocessing و هم چنین threading ممکنه (البته با threading اصن کار نکردم ولی شنیدم بعضی جاها باگ داره ولی خودم اصلا این مورد رو تست نکردم و نمی تونم در موردش نظر بدم ولی با multiprocessing کار کردم و واقعا عالی عمل می کنه) ولی توضیح دادن این ماژول ها خارج از حوصله ی این بحثه و بهتره اونا (به همراه عبارت python parallel processing) رو گوگل کنین

آفلاین ارباب!

  • Sr. Member
  • *
  • ارسال: 448
  • جنسیت : پسر
خوب شد گفتید..
یه مقدار مساله متفاوت تر از اون چیزی بود که تصور می کردم.. در این حالت خاص.. چه برنامتون رو یه هسته اجرا بشه چه رو صد تا هسته.. می خواید وقتی منتظر انجام یه کاری هستید (منتظر موندن برای دریافت پاسخ) کارای دیگه انجام بشن (ارسال درخواست های دیگه..)..
پس به نظرم دست به کار بشید و از همون ماژول multiprocessing استفاده کنید و اگه مشکلی داشتید بگید..:
https://docs.python.org/2/library/multiprocessing.html
https://docs.python.org/3.6/library/multiprocessing.html
از اون مثال اول ایده بگیرید.. می تونید یه تابع f تعریف کنید که کار داخل حلقه رو انجام می ده و ...
« آخرین ویرایش: 09 دی 1395، 03:09 ق‌ظ توسط ارباب! »
Void Linux + XFCE

آفلاین علی رزم دیده

  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1244
  • جنسیت : پسر
  • ali76 سابق
درواقع اون کار ارسال یک سری درخواست به سایت است
که توی اسکریپت باید ۱۰ تا ۱۵ ثانیه منتظر جواب از سایت بماند
اگر بخواهم درخواست ها را تک به تک بفرستم زمانی که برنامه منتظر جواب است میخواهم درخواست های دیگه ارسال بشه
بعد هم جواب ها چنداتا پردازش روشون صورت میگیره
من مشغول نوشتن کامنت قبلی بودم که شما یه کامنت جدید نوشتی و ابعاد جدیدی از قضیه رو توضیح دادی
اون طور که بوش میاد شما می خوای رو یه سایت brute force انجام بدی  ;)
عمل brute force به هیچ عنوان بار سنگینی روی پردازنده نمیاره که شما بخوای از کتابخوانه هایی عین multiprocessing استفاده کنین و بیشتر به سرعت اینترنت شما و سرور مقصد بستگی داره
بزار بیشتر توضیح بدم , شما وقتی می تونین multiprocessing کنین که سرورتون و البته سرور مقصد اصطلاحا multi-threaded باشه یعنی وقتی تو پردازنده ی شما لیست ۵ قسمت شد مودم شما هم بتونه اون ۵ قسمت رو بفرسته و سرور مقصد اون ۵ قسمت رو پردازش کنه و در نهایت شما بتونین اون ۵ قسمت رو دریافت کنین که مودم های معمولی معمولا تک رشته ای هستن و نمی شه چند تا رشته رو با هم بگیرن و بفرستن !
واسه همین ایراد تک رشته ای بودن مودم ها هست که شما وقتی یه فایلی رو با دانلود منیجر مثلا تو ۳۲ هم دریافت می کنین باز هم تاثیر چندانی توی سرعت دریافت نخواهد داشت (تجربه ی من نیشون داده تو دانلود یه فایل ۱ گیگی اگه ۳۰ دقیقه تو حالت عادی طول بکشه وقتی چند قسمتش می کنیم ۲۵ دقیقه طور می کشه که واقعا مقدار زیادی نیس و به پذیرش خطر خرابی فایل دانلود شده نمیارزه)
پس فرقی نداره شما یه قسمت داشته باشین یا ۵ قسمت و بیشتر بستگی به سرعت اینترنت شما و سایت مورد نظر داره

آفلاین Fire.Phoenix

  • Full Member
  • *
  • ارسال: 108
نقل‌قول
اون طور که بوش میاد شما می خوای رو یه سایت brute force انجام بدی  ;)
نه یک بخشی از کار webscript است خود سایت درخواست ها را به تعویق میندازد در نتیجه به سایت هم فشار نمی آید (سایت به طور کلی برای دریافت تعداد بالای درخواست طراحی شده است)
متشکر از راهنمایی ها و مطالبی که گفتید من برم مطالب را بخوانم
« آخرین ویرایش: 09 دی 1395، 01:18 ب‌ظ توسط Fire.Phoenix »