تبليغاتX
XGRID تکنولوژی
 
XGRID تکنولوژی
 
 
پیاده سازی سیستم های توزیع شده
 


استفاده از Thread ها در دلفی



اساس کار ویندوز در اجرای برنامه ها بر روی Thread ها است ، هنگامی که برنامه ای اجرا می شود ، کلیه کدها و فایلهای منبع ( Resource ) آن در یک یا چند Thread قرار می گیرند ، درواقع هرProcess در ویندوز دارای یک یا چند Thread است که اطلاعات Process درآنها قرار دارند و بر روی حافظه موقت بارگذاری شده اند ... ، برنامه ها میتوانند در زمان اجرای خود Thread هایی ساخته و سپس آنها را آزاد نمایند ، کار یک Process زمانی به پایان می رسد که تمام ، Thread های آزاد شده باشند ، در غیر این صورت آن Process بسته نخواهد شد ، پس باید در آزادسازی Thread ها دقت زیادی داشت ...

ساخت Thread و استفاده از آن در برنامه :
در دلفی کلاسی به نام TThread قرار دارد که امکان استفاده از Thread ها را فراهم می سازد ...
برای استفاده از یک Thread ابتدا باید یک نسخه از کلاس TThread را Create کرده و سپس از آن استفاده نمایید
برای ساخت یک Thread به صورت زیر عمل می کنیم :

کد:
Type
 MyThread = Class(TThread)
  private
    …
  protected
    ...
 end;

در کد بالا یک نوع از TThread را ساختیم ...
در یک Thread میتوانید Procedure ها و توابعی را قرار داده و از آنها استفاده نمایید ، توجه داشته باشید که برای فراخوانی توابع و متد ها باید از روش Synchronization ( همزمان سازی ) استفاده نمایید ، شاید با دیدن این کلمات احساس کنید که کار سختی در پیش دارید ، اما اصلا این طور نیست ، این کار با اجرای یک تابع ساده امکان پذیر است که در ادامه توضیح خواهیم داد ...
Thread ها یک Event اصلی به نام OnExecute دارند که مربوط به زمان اجرا شدن آنها است ، تمام کار Thread ها در همین Event انجام می شود ، کدی که در این رویداد می نویسید از زمان اجرا شدن Thread تا زمان Terminate شدن آن اجرا خواهد شد.
نمی توان در یک Thread به صورت مستقیم با اشیای فرم ارتباط داشت ، چنین درخواستهایی از Thread باعث متوقف شدن کار آن خواهد شد و نتیجه مطلوبی نخواهید گرفت ... ، برای دسترسی به اشیاء باید از Procedure های جدا و Synchronize استفاده نمایید تا اختلالی در کار Thread به وجود نیاید ...
ابتدا باید توابع و متد ها را در یک Thread تعریف کرده و کد مورد نظر را در آن بنویسیم ، سپس با تابع Synchronize به روش زیر می توانیم آن را اجرا نماییم :

کد:
Synchronize( My Procedure );

طریقه ایجاد توابع و Procedure ها در Thread مانند سایر کلاسها ( مثلا TForm ) است ، برای مثال فرض کنید متدی داریم که در آن عمل Progress کردن یک ProgressBar را انجام می دهیم ، میتوانیم به صورت زیر این متد را تعریف نماییم :

کد:
Type
 MyThread = Class(TThread)
  private
   procedure doProgress;
  end;

Implementation

procedure doProgress;
begin
  Form1.ProgressBar1.Progress;
end;

ساخت و استفاده از Thread :
در بالا نحوه تعریف یک Thread را توضیح دادیم ، برای استفاده از آن باید یک متغیر با نام Thread تعریف شده تعریف نماییم و از آن استفاده کنیم ...
نکته دیگر این که متد Create برای Thread ها یک پارامتر به نام Suspended دارد که از نوع Boolean می باشد و به صورت پیشفرض دارای مقدار False است ...
این پارامتر مشخص میکند که آیا Thread در حالت متوقف ساخته شود یا اینگه بعد از ساخته شدن بلافاصله در حالت اجرا قرار گیرد ( Thread بعد از ساخته شدن ، متد Execute اش اجرا خواهد شد ، با True کردن این پارامتر ، متد Execute را متوقف کرده و از اجرا شدن کدها جلوگیری می نماییم ) ، بعد از اجرای Thread ممکن است نیاز باشد که برخی از خصوصیات آن را تغییر دهیم ، پس باید به این پارامتر مقدار True دهیم تا Thread ما بعد از ساخته شدن در حالت اجرا نباشد و امکان تغییر خاصیتهای آن وجود داشته باشد ...
برای مثال بهتر است که خاصیت FreeOnTerminate مربوط به Thread ساخته شده را True نماییم تا هنگام فراخوانی متد Terminate برای پایان کار Thread‌ ، آن را آزاد کنیم ...
پس کد ما تا اینجا به شکل زیر درخواهد آمد :

کد:
var
 T : MyThread;
begin
 T := MyThread.Create(True);
 T.FreeOnTerminate := True;
 T.Resume;
end;

در کد بالا Thread ما ساخته شده و سپس خاصیت FreeOnTerminate آن True شده و سپس با استفاده از متد Resume به کار خود ادامه می دهد ( از حالت Suspend بیرون می آید ) ...

کد نویسی در رویداد OnExecute :
هر Thread ای که Create می کنید در حالت پیشفرض رویداد OnExecute را دارا می باشد ، برای این که آن را به دلخواه خود تغییر دهید باید آن را دوباره تعریف کنید ، برای تعریف این رویداد باید از قسمت Protection و وا‍ژه Override استفاده نمایید تا رویداد قبلی Thread از بین رفته و رویداد جدیدی که ایجاد می کنید جایگزین شود ، پس کد شما به این صورت خواهد بود :

کد:
type
 MyThread = Class(TThread)
  private
   ...  
  protected
   procedure Execute; override;
  end;

var

implementation

procedure MyThread.Execute;
begin

end;

اجرای Procedure های تعریف شده ( Synchronization ) :
برای فراخوانی Procedure هایی که تعریف کرده اید باید ار تابع Synchronize استفاده نمایید ( در داخل رویداد OnExecute ) ، برای مثال :

کد:
procedure MyThread.Execute;
begin
 Synchronize(doProgress);
end;

تابع Synchronize یک پارامتر دارد که از نوع TThreadMethod است و Procedure ای که در Thread تعریف کردید باید در آن قرار گیرد ...

مدیریت Thread :
برای استفاده از Thread با متدهای آن آشنایی داشته باشید ...
برای متوقف کردن یک Thread باید از متد Suspend استفاده نمایید ، و برای ادامه کار آن باید از متد Resume استفاده کنید :

کد:
MyThread.Suspend;
...
MyThread.Resume;

برای این که بفهمید آیا Thread ما در حالت Suspend است یا خیر میتوانید از خاصیت Suspended استفاده نمایید ، این خاصیت یک مقدار Boolean دارد که مشخص می کند Thread مورد نظر Suspend شده یا خیر :

کد:
var
 isSuspended : Boolean;
begin
 isSuspended := MyThread.Suspended;
end;

اگر می خواهید که کار یک Thread را کاملا متوقف نمایید ، می توانید از متد Stop استفاده کنید ، در این صورت برای اجرای دوباره Thread باید از متد Execute استفاده نمایید :

کد:
MyThread.Stop;
...
MyThread.Execute;

خاصیت Priority :
اگر در محیط ویندوز برنامه Task Manager را اجرا نموده و به قسمت Process بروید لیست Process های در حال اجرا را می بینید ، اگر بر روی هر کدام از این Process ها راست کلیک نمایید گزینه ای به نام Set Priority می بینید که مقادیری مثل High‌ ، Normal یا Low و ... دارد ، Priority مشخص می کند که در زمان الویت بندی اجرای Thread ها در CPU ، کدام یک ارجعیت دارند و به CPU ابتدا باید به درخواست کدام یک از آنها جواب دهد ، هرچه مقدار Priority یک Thread مقدار بالاتری داشته باشد ، الویت بیشتری خواهد داشت و عملیاتش زودتر انجام خواهد شد ...
می توانید برای Threadخود این خاصیت را تنظیم نمایید ، این خاصیت از نوع TThreadPriority می باشد ، در تصویر زیر مقادیری که می توانید به عنوان Priority قرار دهید مشخص شده است :


ThreadID :
این خاصیت شناسه ای برای Thread شما است که هم در زمان ساخت ( در زمان Debug‌ ) و هم در زمان اجرای برنامه می توانید از آن استفاده نمایید ، هنگامی که قصد Debug کردن برنامه خود در محیط دلفی را دارید ، پس از اجرا کردن برنامه اگر از منوی View گزینه Debug Windows و سپس گزینه Threads را انتخاب نمایید ، پنجره ای باز شده و لیستی از Thread های در حال اجرا در برنامه شما را نمایش میدهد که هرکدام از آنها دارای شناسه ای به نام ThreadID هستند ، با داشتن این مقدار می توانید Thread مورد نظر خود را در این پنجره پیدا نمایید ...
این مقدار را می توانید به روش زیر بدست آورید :

کد:
var
 MyThreadID : Cardinal;
begin
 MyThreadID := MyThread.ThreadID;
end;


خروج از Thread و آزاد کردن آن :
رویداد OnTerminate :
Thread یک رویداد دیگر دارد که میتوانید آن را مانند OnExecute تنظیم نمایید و تغییر دهید ، این رویداد زمانی اتفاق می افتد که Thread مورد نظر Terminate‌ شود ، اما متد دیگری به نام DoTerminate وجود دارد که این رویداد را اجرا میکند بدون اینکه Thread مورد نظر Terminate شود ( یا شده باشد ) ، با متد ...

---------

اگر یادتان باشد ،‌ ما در هنگام ساخت Thread مقدار خاصیت FreeOnTerminate‌آن را True کردیم پس اگر آن را Terminate نماییم ، آزاد ( Free ) خواهد شد ، با متد Terminate میتوانید به کار یک Thread پایان دهید :

کد:
MyThread.Terminate;

در برخی موارد ممکن است Thread مورد نظر Terminate نشود ! ، درواقع هنگامی که ما متد Terminate را اجرا می کنیم ، کار عمده ای انجام نمی شود ، بلکه فقط خاصیت Terminated مربوط به Thread بر روی True تنظیم می شود ! ، درواقع این عمل به Thread اعلام میکند که به زودی ممکن است کارش پایان یابد ، باید برای پایان کار Thread‌ ، بعد از اجرا این متد با استفاده از متد Exit ( مربـوط به Thread نیست ) از رویداد OnExecute خارج شد ( دستور Exit در دلفی برای خروج از یک رویه ( تابع یا ... ) به کار می رود ) :

کد:
procedure MyThread.Execute;
begin
 Synchronize(doProgress);
 …
 MyThread.Terminate;
 Exit;
end;

توجه داشته باشید که در قسمتهای مختلف کد باید چک کنید که آیا Terminated مربوط به Thread مقدار True دارد یا خیر و اگر مقدار True داشت با استفاده از دستور Exit از رویداد خارج شوید :

کد:
procedure MyThread.Execute;
begin
 if MyThread.Terminated then
    Exit;
 …
 if MyThread.Terminated then
    Exit;
 …
 MyThread.Terminate;
 Exit;
end;

علاوه بر موارد بالا می توانید از متد WaiteFor استفاده نمایید ، متد WaiteFor تا زمانی که کار Thread‌ به پایان برسد کارش تمام نخواهد شد ، درواقع می توانید کد Exit را بعد از این متد بنویسید تا خیالتان از بابت پایان کار Thread راحت شود ! :

کد:
procedure MyThread.Execute;
begin
 if MyThread.Terminated then
    Exit;
 …
 if MyThread.Terminated then
    Exit;
 …
 MyThread.Terminate;
 MyThread.WaiteFor;
 Exit;
end;



امیدوارم مفید بوده باشه ...

PDF این مقاله رو می تونید از اینجا دانلود کنید ...


منبع : http://barnamenevis.org/forum/showthread.php?t=79463

 

 |+| نوشته شده در  سه شنبه بیست و هشتم اسفند 1386ساعت 11:6 قبل از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام

Multi threading در پیتون

موضوع هایی که می خواهیم در موردشان بحث کنیم:

  • 1. مقدمه
  • 2. نخها و پروسس ها
  • 3. نخها و پیتون
  • 4. ماژول thread
  • 5. ماژول threading

در این موضوع , ما می خوایم راههایی که شما می توانید اجرای موازی و همزمان رو در کد خودتون استفاده کنید و چگونکی استفاده ازبرنامه نویسی Multithread (MT) و ایجاد آن در پیتون. این مقاله مثل تمام مقالات من کامل نیست و من فقط مطالبی که به نظر مهم هستند و به کمکتون می یاد را توضیح می دهم.

  • مقدمه:

قبل از هر چیز باید بدانید که برنامه نویسی چند نخی (Multithread) یکی از قابلیت هایی است که مستقیما به سیستم عامل مربوط می شود یعنی سیستم عامل شما باید از این شیوه پشتیبانی کند (سیستم عامل ویندوز این قابلیت را دارد). هر وقت برنامه ای شروع به اجرا می کند ویندوز یک ( نخ) به ان اختصاص می دهد این Thread در واقع رابط بین برنامه و CPU است . همونطور که می دانید CPU برای اینکه بتواند چند وظیفه را بصورت هم زمان انجام دهد , به هر Thread یک زمان مشخص اختصاص می دهد (با توجه به اولویت Thread). مثلا اگر ما دو Thread در حال اجرا داشته باشیم CPU یک زمان خاصی را به Thread اولی اختصاص می دهد تا کارش را انجام دهد پس از اتمام زمان نوبت به Thread بعدی می رسد و به همین ترتیب...

  • نخ ها و پروسس ها:
  • پروسس چیست:

برنامه های کامپیوتر صرفا اجرا پذیر هستند, باینری (یا طور دیگر ), این برنامه ها روی دیسک قرار دارند. اینها نمی توانند کاری انجام بدهند(به اصطلاح مرده هستند) تا زمانی که داخل حافظه بارگذاری شوند و از سیستم عامل درخواست کنند. پروسس یک برنامه در حال اجرا است. هر پروسس یک ادرس فضا , حافظه و یک پشته داده دارد. سیستم عامل کنترل کننده تمام پروسس های در حال اجرا بر روی سیستم است, و زمان رو میان انها به طور خوب تقسیم می کند. پروسس ها می توانند چند شاخه بشوند یا یک پروسس جدید برای انجام دیگر کارها ایجاد کنند, هر یک از این پروسس های جدید حافظه و پشته داده و... خودشان را دارند ولی نمی توانند به طور عمومی از اطلاعات سهمی داشته باشند مگر اینکه از IPC ها استفاده کنند.

  • نخ چیست:

Thread ها یا نخ ها به قطعه کدهایی گفته می شود که به صورت موازی و همزمان با هم اجرا می شوند و به شما این امکان را می دهند برنامه هایی را طراحی و پیاده سازی کنید که می توانند چندین کار را با هم انجام دهند به طور مثال : جستجوی چند فایل یا گرفتن اطلاعات از طریق شبکه و ذخیره انها در دیسک. البته اصولا نخ ها به صورت همزمان اجرا نمی شوند بلکه CPU براساس تنظیم زمان خود یک زمان غیر قابل درک برای انسان را در نظر می گیرد سپس در این مدت زمان یک کار را انجام داده و پس از اتمام این زمان به سراغ کار بعدی می رود به اصطلاح در کارهای خود سوییچ می کند. به این مدت زمان کوتاه اصطلاحا Time Slice یا پرش زمان می گویند.

  • نخ ها و پیتون:
  • دسترسی به نخها در پیتون:

پیتون از برنامه نویسی چندنخی پشتیبانی می کند. پس باید سیستم عامل در حال اچرا ان را پشتیبانی کند بیشتر ورژنهای Unix , Solaris , Linux و Windows از این قابلیت پشتیبانی می کنند و فکر کنم مکینتاش از این قابلیت برخوردار نیست.

  • ماژولهای نخ کشی پیتون:

پیتون چند ماژول برای پشتیبانی ازبرنامه نویسی MT شامل thread , threading و Queue را اماده دارد. ماژولهای thread و threading به برنامه نویس اجازه ساختن و اداره نخ را می دهند. ماژول thread برای کار با نخ به صورت ساده و پایه ای است ولی ماژول threading خصوصیات سطح بالا و کاملی از برنامه نویسی نخ در اختیار ما قرار می دهد. ماژول Queue به کاربر اجازه ساختن صف داده را می دهد. این ماژول در محدوده بحث ما نیست و شاید در مقاله دیگری در مورد ان بحث کردیم.

  • ماژول thread :

این ماژول همان طور که گفته شد امکانات کم و سطح پایینی برای کار با چندین نخ در اختیار ما قرار می دهد. تابع اصلی و کلیدی این ماژول start_new_thread() است این تابع خیلی به apply() شباهت دارد.من در اینجا ابتدا چند تا از متدهای این تابع را توضیح می دهم.

1.start_new_thread(function, args, kwargs = None)

شروع یک نخ جدید و عددی که مشخص کننده هویت ان است نخ با گرفتن یک لیست از ارگومانها (که باید در داخل tuple باشند) تابع را اجرا می کند.ارگومان kwargs اختیاری است که با دیکشنری از کلمات کلیدی ارگومانها مشخص می شود. وقتی تابع اجرا شد و بازگشتی ان مشخص شد نخ از کار می افتد.


2.interrupt_main()

ایجاد یک KeyboardInterrupt در نخ اصلی , یک subthread می تواند می تواند از وقفه ایجاد شده در نخ اصلی استفاده کند.

3.exit()

باعث اجرای استثنای SystemExit می شود. اگر نتوانست پیدا کند باعث توقف نخ می شود.

4.allocate_lock()

برگرداندن یک شی lock جدید . متدهای قفل ها در زیر امده اند.

5.get_ident()

عدد مشخص کننده هویت نخ در حال جاری را برمی گرداند این عدد یک عدد غیر صفر است. این اعداد که مشخص کننده هویت نخ هستند هیچ گاه بعد از استفاده نخ و خارج کردن ان دور انداخته نمی شوند و می توانند به نخ هایی که بعدا ایجاد می شوند نسبت داده شوند.(مثل استفاده از دایل اپ برای کانکت شدن به اینترنت که هر دفعه یک ای پی به ما داده می شود و بعد از قطع ارتباط این ای پی به شخص دیگری که به اینترنت وصل می شود داده می شود...)


[ویرایش] متدهای مطلق به شی Lock :

1.acguire([waitflag])

برای بدست اوردن و جستجوی lock های قطعی است.

2.locked()

اگر یک lock بدست اورد 1 در غیر این صورت نتیجه 0 است

3.release()

برای ازاد کردن lock



برای فهمیدن و درک چنین بحث هایی در برنامه نویسی باید خیلی تمرین کرد و مثال های مختلفی را تجزیه و تحلیل کرد. مثال پایین یک مثال خوب و ساده برای دیدن نتیجه کار بعضی از توابع و متدها است. زیاد هم سخت نیست کمی دقت کنید متوجه می شوید.


01    #Using thread and Locks
02
03    import thread
04    from time import sleep, time, ctime
05    loops = [4, 2]
06    def loop(nloop, nsec, lock):
07        print 'start loop', nloop, 'at:', ctime(time())
08        sleep(nsec)
09        print 'loop', nloop, 'done at:', ctime(time())
10        lock.release()
11    def main():
12        print 'starting threads…'
13        locks = []
14        nloops = range(len(loops))
15
16        for I in nloops:
17            lock = thread.allocate_lock()
18            lock.acquire()
19            locks.append(lock)
20       
21        for I in nloops: 
22            thread.start_new_thread(loop, \
23                (I, loops[i], locks[i])) 
24
25        for I in nloops:
26            while locks[i].locked(): pass
27
28        print 'all DONE at:', ctime(time())
29    
30    if __name__ == '__main__':
31        main()
32


  • ماژول threading :

اگر شما قادر به کار کردن با ماژول thread باشید و درکی از آن داشته باشید از این ماژول نیز می توانید بدون توضیح استفاده کنید البته این ماژول امکانات فراوانی دارد که در ماژول thread وجود ندارد ولی به هر حال یاد گیری آنها ساده است. چون توضیح این ماژول به طور کامل خیلی وقت می برد و باعث طولانی شدن مطالب و شاید سردرگمی شما شوند.

در حال تکمیل توسط pyth0n

منبع:

  • 1.راهنمای خود پیتون
  • 2.کتاب Core Python
 
 
 
 |+| نوشته شده در  شنبه بیست و پنجم اسفند 1386ساعت 8:16 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام

جایزه صدهزار دلاری برای تجزیه یک عدد

تجزیه اعداد بزرگ به عوامل اول یکی از مشکلترین مسائل ریاضی است که تا حالا راه حل تحلیلی برای آن پیدا نشده. به همین دلیل موفقترین الگوریتمهای رمزنگاری امروزه از روشهایی استفاده می‌کنند که به نوعی به دانستن عاملهای اول یک عدد بزرگ بعنوان کلید رمزگشایی احتیاج دارند. یکی از این الگوریتمها RSA است که اسمش مخفف اولین حرف اسامی مخترعین آن است.

آزمایشگاه RSA که برروی روشهای رمزنگاری و امنیت اطلاعات کار می‌کند برای آنکه نشان دهد استفاده از این سیستم رمزنگاری به اندازه کافی کارآمد است، مسابقه‌هایی را ترتیب داده و به افرادی که بتوانند اعداد بزرگ را به عوامل اولشان تجزیه کنند جایزه‌های نقدی می‌دهد. این اعداد توسط الگوریتمهای RSA ایجاد شده اند و دو عامل اول بزرگ دارند. طول این اعداد در سیستم باینری از ۵۷۶ تا ۲۰۴۸ بیت متغیر است. عدد ۱۰۲۴ بیتی (۳۰۹ رقم در سیستم اعشاری) با جایزه یکصدهزار که برای تجزیه به مسابقه گذاشته شده این است:

13506641086599522334960321627880596993888147560566
70275244851438515265106048595338339402871505719094
41798207282164471551373680419703964191743046496589
27425623934102086438320211037295872576235850964311
05640735015081875106765946292055636855294752135008
52879416377328533906109750544334999811150056977236
890927563

در حال حاضر آخرین عددی که تجزیه شده ۶۴۰ بیتی بوده که معادل ۳۰ سال برروی یک پروسسور AMD Opteron 2.2GHz زمان‌ برده. البته تجزیه این عدد به دلیل استفاده از چندین پروسسور بطور موازی در عمل پنج ماه زمان برده. تیم برنده در واقع نشان دادند:

 31074182404900437213507500358885679300373460228427
27545720161948823206440518081504556346829671723286
78243791627283803341547107310850191954852900733772
=4822783525742386454014691736602477652346609
16347336458092538484431338838650908598417836700330
92312181110852389333100104508151212118167511579
X
1900871281664822113126851573935413975471896789968
515493666638539088027103802104498957191261465571

و ۲۰ هزار دلار بردند! ظاهراً ساده به نظر می‌رسه ولی در عمل خیلی مشکل است. برای امتحان این عدد را به نرم‌افزار Mathematica دادم تا تجزیه کند ولی نتیجه‌ای حاصل نشد!

اگر کسی بتواند برنامه‌ای بنویسد که از قابلیت پردازش موازی برروی کامپیوترهای مختلف متصل به اینترنت استفاده کند (در زمان بیکاری پروسسور، چیزی شبیه برنامه SETI at Home یا برنامه‌های مشابه)، می‌شود این مسئله را حل کرد. کسانی که در این کار مشارکت کرده‌اند هم بعداً به نسبت زمانی که در اختیار این برنامه گذاشته‌اند از جایزه سهم خواهند برد.   

یکی از کاندیداهای قوی برای حل این قبیل مسائل کامپیوترهای کوانتمی هستند که بطور بنیادی قابلیت انجام محاسبات موازی را دارند. در ضمن چند هفته قبل شرکتی با اسم  D-Wave اولین کامپیوتر کوانتمی با ۱۶ Qbit را آزمایش کرد.

لینکها:
اعداد اول مسابقه RSA
اطلاعات بیشتری درباره الگوریتم RSA

 

 |+| نوشته شده در  شنبه بیستم بهمن 1386ساعت 8:52 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
نحوه كار با Distributed Computing Toolbox بطور خلاصه:

پيش از شروع كار با اين جعبه ابزار بايد آنرا نصب كنيد. ضمنا توجه داشته باشيد كه MATLAT نسخه 7.0.4 يا بالاتر (اگر به بازار آمده است) روي تمام كامپيوترها نصب شده باشد. حالا در خط فرمان (cmd) اين دستورات را تايپ كنيد:

cd MATLABROOT\toolbox\distcomp\bin\win32
mdce install


پس از اجراي دستور فوق، سرويس mdce نصب مي‌شود و هر بار با بالا آمدن سيستم عامل، شروع مي‌شود. مي‌توانيد اين موضوع را اينجا چك كنيد (Control Panel->Administrative Tools->Services). سرويسي به اسم MATLAB Distributed Computing Engine Service خواهيد ديد كه مربوط به همين جعبه ابزار است. اگر سرويس فوق شروع نشده باشد، به سادگي و با تايپ mdce start در خط فرمان و آدرس بالا (MATLABROOT\toolbox\distcomp\bin\win32) شروعش كنيد. من و سيب قبلا توي اتاق ICT اين كار را انجام داديم ولي اگر باز هم مشكلي بود، به سيب مراجعه كنيد (چون بيشتر از من توي بخش ديده مي‌شه).
بهتر است اول كمي در مورد كلماتي كه در ادامه مي‌بينيد، توضيح بدهم. در اينجا، به يك برنامه توزيع شده، job گفته مي‌شود كه اداره آن به عهده jobmanager مي‌باشد. هر job به قسمتهايي به نام task تقسيم مي‌شود كه مي‌توانند بصورت مجزا و همزمان روي كامپيوترهاي مختلف اجرا بشوند. سپس jobmanager، هر task را براي اجرا به يك worker مي‌فرستد. پس روي هر كامپيوتر بايد حداقل يك سرويس worker اجرا شده باشد. بديهيست كه شبكه احتياج به حداقل يك jobmanager دارد و هر jobmanager هم حداقل به يك worker نياز دارد. ابتدا بايد jobmanager اجرا شود، پس در خط فرمان تايپ كنيد (با همان آدرس قبلي):

startjobmanager -name MyJobManager


با اين دستور يك jobmanager به نام MyJobManager، شروع به كار مي‌كند. حالا روي هر كامپيوتر يك worker راه‌اندازي كنيد (به ياد داشته باشيد كه براي اجراي يك برنامه توزيع شده تحت MATLAB نيازي نيست كه همه جا MATLAB در حال اجرا باشد، ولي نصب MATLAB روي همه كامپيوترها الزاميست):

startworker -jobmanager MyJobManager


با اجرا اين دستور در هر كامپيوتر يك worker متعلق به jobmanagerي به نام MyJobManager، شروع خواهد شد. اگر بخواهيد در يك كامپيوتر بيش از يك worker براي يك jobmanager يكسان داشته باشيد با سويچ name- به هر كدام يك اسم يكتا بدهيد. ضمنا فراموش نكنيد كه پس از اتمام كار، اجراي workerها و jobmanager ها رو متوقف كنيد:

stopworker
stopjobmanager -name MyJobManager


حالا نوبت برنامه نويسي است. MATLAB را اجرا كنيد و در پنجره فرمان، يك jobmanager در شبكه پيدا كنيد:

all_managers = findResource('jobmanager')
jm = all_managers(1)


اگر به دنبال يك jobmanager با نام خاصي هستيد، اين دستور پيشنهاد مي‌شود:

jm = findResource('jobmanager', 'Name', 'MyJobManager')


با اجراي دستور مفيد زير:

get(jm)


خصوصيات jm از جمله تعداد workerها و وضعيت آنها را مي‌توان مشاهده نمود.
حالا يك job درون jm بسازيد:

job1 = createJob(jm)


مي‌توان مشخصات job1 را هم ديد:

get(job1)


مي‌بينيد كه وضعيت job1 فعلا pending است. با دستورات زير، چند task درون job1 ايجاد كنيد:

createTask(job1, @rand, 1, {3,3});
createTask(job1, @rand, 1, {3,3});
createTask(job1, @rand, 1, {3,3});
createTask(job1, @rand, 1, {3,3});
createTask(job1, @rand, 1, {3,3});


و بعد:

submit(job1)


با دستور زير نتيجه اجراي job1 را ببينيد:

results = getAllOutputArguments(job1);
for i = 1:5
disp(results{i})
end
0.9501 0.4860 0.4565
0.2311 0.8913 0.0185
0.6068 0.7621 0.8214

0.4447 0.9218 0.4057
0.6154 0.7382 0.9355
0.7919 0.1763 0.9169

0.4103 0.3529 0.1389
0.8936 0.8132 0.2028
0.0579 0.0099 0.1987

0.6038 0.0153 0.9318
0.2722 0.7468 0.4660
0.1988 0.4451 0.4186

0.8462 0.6721 0.6813
0.5252 0.8381 0.3795
0.2026 0.0196 0.8318


تابع مفيد ديگري هم به نام dfeval وجود دارد كه در صورتي كه تمام taskها مربوط به اجراي تابعي يكسان باشند، بهتر است از آن استفاده كنيد:

y = dfeval(@rand,{1 2 3})
y =
[ 0.9501]
[2x2 double]
[3x3 double]


مي‌بينيد كه ديگري نيازي به تعريف job و task نيست. اما اين تابع پنجره فرمان MATLAB را تا اجراي كامل قفل مي‌كند، پس اگر خواستيد همزمان با اجراي برنامه خود بتوانيد با پنجره فرمان كار كنيد، از تابع dfevalasync استفاده كنيد. با اين تفاوت كه بايد پيش از درخواست نتيجه از اجراي كامل همه taskها اطمينان حاصل كنيد:

Job1 = dfevalasync(@myfun, 2, {a b c d}, {e f g h}, {w x y z});

و بعد:

waitForState(Job1,'finished')
data = getAllOutputArguments(Job1)
 
 
 
 |+| نوشته شده در  چهارشنبه بیست و پنجم مهر 1386ساعت 7:12 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
Multithreading در VB

برای پیاده سازی چند ریسمانی در ویژوال بیسیک می توانید از مقاله زیر استفاده نمایید

لینک دانلود : >>>     http://salimipour.ir/Multithreading.pdf

 

 |+| نوشته شده در  دوشنبه بیست و ششم شهریور 1386ساعت 1:53 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
آموزش برنامه نویسی Multi-threading در C++ به وسیله SDL

قسمت دوم

 

 Semaphore:

 

سمافر در لغت به معنی با پرچم به هم علامت دادن است و کار ان شبیه کار موتکس است با این فرق که بیشتر از دو مقدار locked و unlocked می تواند به خود بگیرد.و سمافر ها حاوی یک مقدار عددی هستند که بسته به شرایط می تواند مقادیر مثبت منفی و صفر به خود بگیرد و تصمیم می گیرد thread ها منتظر بمانند یا کارشان را انجام دهند.سمافرها راه بهتری را برای برنامه ریزی thread ها در اختیار ما می گذارند.

البته برای برنامه های ساده Multi-threading موتکس ها کافی به نظر می رسند.

 

برخلاف موتکس که دارای دو مقدارمیباشد یک سمافر در SDL دارای 2 به توان 32 حالت می باشد تمام مقادیری که یک Uint32 می تواند به خود بگیرد و وقتی مقدار ان صفر است

شبیه موتکس قفل شده رفتار می کند.

 

برای ساختsemaphore  می توانید از تابع  SDL_CreateSemaphore  استفاده کنید.

SDL_sem *SDL_CreateSemaphore(Uint32 initial_value);

این تابع مقدار اولیه سمافر را دریافت می کند سپس یک اشاره گر به SDL_sem بر می گرداند.

برای نابود کردن یک سمافر هم می توانید از تابع SDL_DestroySemaphore استفاده کنید.

void SDL_DestroySemaphore(SDL_sem *sem);

که یک سمافردریافت و ان را از بین می برد.

 

سمافرها از Locked و Unlocked استفاده نمی کنند و به جای ان از Wait و Post استفاده می کنند.این دو مثل lock و unlock رفتار می کنند وقتی که در یک سمافر wait کنید اگر مقدار ان بزرگتر از صفر باشد یک واحد از ان کم می شود و سپس thread مورد نظر کار خود را به پایان می رساند.اگر مقدار ان برابر صفر باشد می ایستد تا مقدار ان بزرگتر از صفر شود و سپس اجرا می شود.

وقتی یک سمافر را post می کنید مثل unlock کردن ان می ماند ویکی به مقدار ان اضافه می شود تا thread های دیگر بتوانند کار خود را انجام دهند.

برای wait کردن بر روی سمافر شما باید از تابع  SDL_SemWait  استفاده کنید.   

int SDL_SemWait(SDL_sem *sem);

این تابع صبر می کند تا مقدار سمافر مثبت سود سپس یکی از ان کم می کند و مقدار را بر می گرداند در صورت بروز خطا مقدار 1- را بر می گرداند.

 

همچنین شما می توانید با تایین زمان منتظر یک سمافر باشید

int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout);

شما می توانید مقدار یک سمافر را با post کردن ان زیاد کنید.

int SDL_SemPost(SDL_sem *sem);

همچنین شما می توانید مقدار یک سمافر را بوسیله تابع SDL_SemValue تشخیص دهید

Uint32 SDL_SemValue(SDL_sem *sem);

که یک سمافر می گیرد و مقدار ان را بر می گرداند.

در زیر مثالی از سمافر امده است توجه کنید متغییر ها قبلا تعریف شده اند :

//create semaphore

g_pSemaphore=SDL_CreateSemaphore(0);

//create three threads

g_pThread[0]=SDL_CreateThread(ThreadFunction,(void*)1);

g_pThread[1]=SDL_CreateThread(ThreadFunction,(void*)2);

g_pThread[2]=SDL_CreateThread(ThreadFunction,(void*)3);

//wait for a second

SDL_Delay(1000);

//post to the semaphore

SDL_SemPost(g_pSemaphore);

در اول کار ما یک سمافر با مقدار اولیه صفر تعریف می کنیم که تا وقتی سمافر post نشود همه thread ها باید منتظر بمانند.سپس 3 thread تعریف می کنیم بعد یک ثانیه صبر می کنیم تا thread ها اماده شوند و سپس سمافر را post می کنیم تا thread ها شروع به کار کنند.

 

وتابع thread ما هم به شکل زیر است.

//thread function

int ThreadFunction(void* data)

{

          //grab thread number

          int threadnumber=(int)data;

          //wait for semaphore

          fprintf(stdout,”Thread %d: Initialized. ”,threadnumber);

          fprintf(stdout,”Thread %d: Waiting for semaphore. ”,threadnumber);

          SDL_SemWait(g_pSemaphore);

          //post to semaphore

          fprintf(stdout,”Thread %d: Done waiting for semaphore. ”,threadnumber);

          fprintf(stdout,”Thread %d: Posting semaphore. ”,threadnumber);

          SDL_SemPost(g_pSemaphore);

          //wait for semaphore again before terminating

          fprintf(stdout,”Thread %d: Waiting for semaphore before terminating.

          ”,threadnumber);

          SDL_SemWait(g_pSemaphore);

          //terminate

          fprintf(stdout,”Thread %d: Terminating. ”,threadnumber);

          SDL_SemPost(g_pSemaphore);

          //return 0

          return(0);

}

هر thread دو بار منتظر سمافر می شود یک بار در شروع thread و یکبار در موقع پایان thread . و نتایج را در فایل stdout.txt می ریزد.(که در اینجا کد مربوط به فایل را در اول کار ننوشتم)

 

1.thread 1 ساخته میشود و منتظر سمافر می شود.

2. thread 2 ساخته میشود و منتظر سمافر می شود.

3. thread3 ساخته میشود و منتظر سمافر می شود.

4.برنامه سمافر را post می کند.

5.ترید 1 از انتظار بیروم می اید و سمافر را post می کند و دوباره منتظر می شود.

6.ترید 2 از انتظار بیروم می اید و سمافر را post می کند و دوباره منتظر می شود.

7.ترید 3 از انتظار بیروم می اید و سمافر را post می کند و دوباره منتظر می شود.

8.سراخر هر 3 ترید بسته می شوند(با جزییاتی که خودتان حدث بزنید).

 

همانطور که می بینید سمافر راه بهتری جلوی روی ما می گذارد و مثلا اگر در برنامه 2 post را می فرستادیم 2 تا thread با هم کار می کردند.

 

 

متغییرهای شرطی :

سر اخر به متغییر های شرطی می رسیم که روشی است برای استفاده درست از موتکس و thread است و بر خلاف موتکس و سمافر دارای حالت (مثل locked یا unlocked) نیست 

SDL_cond *SDL_CreateCond(void);

بوسیله این تابع می توانیم یک متغییر شرطی تعریف کنیم.

و به وسیله تابع زیر می توانیم یک متغییر شرطی را از بین ببریم.

void SDL_DestroyCond(SDL_cond *cond);

 ...

به منظور این که سمافر ها تمام نیاز ما را بر طرف می کنند من فعلا متغییر های شرطی را توضیح نمی دهم اگر کسی نیاز به توضیح داشت به من بگویید!

 

 

 

 |+| نوشته شده در  جمعه دوم شهریور 1386ساعت 7:39 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
آموزش برنامه نویسی Multi-threading در C++ به وسیله SDL

(قسمت اول)

احتمالا چیزهایی در مورد برنامه ها Multi-threaded شنیده اید یا اسم فن اوری جدید Intel به اسم Hyper-Threading را شنیده اید که اگر این فناوری بر روی CPU فعال باشد CPU جوری رفتار می کند که سیستم عامل فرض کند به جای یک CPU 4 عدد CPU در سیستم موجود است که در ان موقع اگر سیستم عامل روی این قسمت کار کرده باشد می تواند به خوبی از این خاصیت استفاده کند و مثلا اجرا برنامه ها را بین 4 CPU تقسیم کند که سرعت به طرز قابل توجهی بالا می رود فعلا که دارم این مقاله را می نویسم بین سیستم عامل هایی که برای PC موجود است Linux Fedora Core بین سیستم عامل های دیگر می تواند به بهترین نحو از چند CPU در ان واحد استفاده کند که می تواند تا حدود 60-70 % از این قابلیت استفاده کند.و البته ویندوز هم به مقدار قابل توجهی از این خاصیت پشتیبانی می کند

و در حال حاضر این خاصیت SDL در سیستم عامل MacOS X کار گذاشته نشده است به خاطر این که اساسا PCهای Macintosh تک CPU هستند و نیازی به همچین کاری احساس نمی شد.

 

به این نوع برنامه نویسی برنامه نویسی موازی هم گفته می شود که قدرت فوق العاده ای به برنامه نویس می دهد که چند کار را در یک زمان انجام دهد.

 

Thread در برنامه نویسی به پروسه ای می گویند که بخشی از یک پروسه بزرگتر یا یک برنامه باشد.

 

همانطور که گفتم برنامه نویسی Multi-threading به شما قدرت فوق العاده ای برای اجرای چند کار در یک زمان را می دهد(البته بر روی سیستم های تک CPU این یک بحث تئوری است ولی فوق العاده به درد به خور حتی در ساخت بازی) در استفاده از thread ها باید نهایت دقت را بخرج دهید.

 

یک thread هم زمان با Main برنامه شما اجرا می شود و ازدر تمام منابع  برنامه مثل فایل ها حافظه و... باmain شریک می شود و مشکل وقتی پیش می اید که یک thread در چیزی با main شریک شود که نباید با ان در Main شریک شود مثل حافظه گرافیکی یا استفاده از صدا. و چیزی که باید یادتون باشد این است که یک thread هیچ وقت از حافظه گرافیکی به طور مستقیم استفاده نکند.

 

خوب اول ببینیم چه گونه می توانیم یک thread ایجاد کنیم.

 

SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data);

این تابع دو پادامتر دریافت می کند یک اشاره گر به تابع و داده ای که باید تابع بپذیرد و نوع برگشتی ان هم از نوع اشاره گر به SDL_Thread است.

تابع شما شکلی مانند شکل زیر دارد

int ThreadFunction(void* data);

که این تابع یک پارامتر برای پردازش دریافت می کند و یک مقدار int برمیگرداند وقتی thread مرد این مقدار بر گشت داده می شود.

اگر به هر طریقی بخواهید یک Thread را متوقف کنید می توانید از تابع SDL_KillThread استفاده کنید یک مقدار خشن به نظر می رسد ولی تا حالا کسی پیدا نشده که از حقوق thread ها دفاع کند!!!

void SDL_KillThread(SDL_Thread *thread);

اگر می خواهید یک مقدار با حوصله تر یک thread را متوقف کنید می توانید از SDL_WaitThread استفاده کنید.

void SDL_WaitThread(SDL_Thread *thread, int *status);

این تابع یک thread را دریافت کرده و سپس یک اشاره گربه یک عدد صحیح می گیرد و منتظر اتمام کار thread می شود و مقدار برگشتی را در status قرار می دهد اگر به مقدار برگشتی اهمیتی نمی دهید می توانید مقدار NULL را به عنوان پارامتر دوم بفرستید.

 

هر thread یک ID 32 بیتی مخصوص خود است که برای مدیریت thread ها می تونید ازش استفاده کنید و به وسیله فراخوانی تابع SDL_ThreadID درون thread می توانید مقدار ان را بیابید.

Uint32 SDL_ThreadID(void);

البته اگر بخواهید از بیرون Thread شناسه ان را بدست اورید می توانید از تابع زیر استفاده کنید.

Uint32 SDL_GetThreadID(SDL_Thread *thread);

 

نکته : برای استفاده از thread ها حتما باید فایل SDL_Thread.h را بارگزاری نمایید و در thread ها نیازی به استفاده از SDL_Init نیز وجود ندارد.

 

MUTEX:

موتکس راه ساده ای برای بر قرار کردن ارتباط بین Thread ها است و یکی از این دو حالت رو به خودش می گیرد Locked و Unlocked . وقتی یک موتکس به وسیله یک thread قفل می شود و thread دیگری خواهان قفل کردن Mutex می شود باید منتظر بماند تا thread قبلی ان را از حالت قفل بیرون بیاورد.

شما به راحتی می توانید بوسیله تابعSDL_CreateMutex  یک Mutex بسازید.

SDL_mutex *SDL_CreateMutex(void);

این تابع هیچ پارامتری نمی گیرد و یک اشاره گر به SDL_mutex بر می گرداند.

برای نابود کردن یک موتکس هم می توانید از تابعSDL_DestroyMutex استفاده کنید

void SDL_DestroyMutex(SDL_mutex *mutex);

شما همچنین می توانید به وسیله تابع SDL_MutexP یا ماکرو SDL_LockMutex یک موتکس را قفل کنید.

int SDL_mutexP(SDL_mutex *mutex);

این تابع یکی از این دو کار را انجام می دهد اگر موتکس ازاد بود ان را قفل می کند و اگر قفل بود منتظر می شود تا ازاد شود سپس ان را قفل می کند.

همچنین از تابع SDL_mutexV می توانید برای ازاد کردن یک موتکس استفاده کنید.

int SDL_mutexV(SDL_mutex *mutex);

یا ازمیتوانید از ماکرو SDL_UnlockMutex استفاده کنید.

یک نمونه ساده ولی جالب از استفاده از Mutex :

g_pMutex=SDL_CreateMutex();

SDL_LockMutex(g_pMutex);

g_pThread=SDL_CreateThread(ThreadFunction,NULL);

SDL_UnlockMutex(g_pMutex);

SDL_WaitThread(g_pThread,NULL);

در اینجا ما در ابتدا یک موتکس می سازیم سپس  ان را قفل می کنیم سپس یک thread می سازیم و بعد از ان mutex را از حالت قفل بیرون می اوریم و منتظر توقف thread می شویم.

تابع thread مان هم به شرح زیر است.

int ThreadFunction(void* data)

{

    fprintf(stdout,”Thread %d: Initialized! ”,SDL_ThreadID());

    fprintf(stdout,”Thread %d: Attempting to lock mutex. ”,SDL_ThreadID());

    SDL_LockMutex(g_pMutex);

    fprintf(stdout,”Thread %d: Mutex is locked. ”,SDL_ThreadID());

    fprintf(stdout,”Thread %d: Unlocking mutex. ”,SDL_ThreadID());

    SDL_UnlockMutex(g_pMutex);

    fprintf(stdout,”Thread %d: Terminating. ”,SDL_ThreadID());

    return(0);

}

این تابع کار خهصی انجام نمی دهد غیر از دادن گزارش کار به ما; در ابتدای کار سعی میکند موتکس را قفل کند ولی چون قبلا قفل شده می ایستد تا ازاد شود سپس قفل میکند و ازاد می کند و متوقف می شود.

 

 

 |+| نوشته شده در  جمعه دوم شهریور 1386ساعت 7:19 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
محاسبات موازی - بخش ششم - مدل های برنامه نویسی موازی

مدل های برنامه نویسی موازی

      
  • چندین مدل برنامه نویسی رایج وجود دارد :

          حافظه مشترک - Shared Memory
          موضوعی - Threads ( معادل دیگری همچون ریسمانی نیز بیان شده است )
          انتقال پیام - Message Passing
          داده موازی - Data Parallel
          مرکب - Hybrid

          
  • اگر چه ممکن است معلوم نباشد ،  ولی این مدل ها به نوع خاصی از معماری کامپیوتر یا حافظه اختصاص ندارند. در حقیقت ، هر یک از این مدل ها می توانند ( از نظر تئوری ) بر روی هر سخت افزار اصولی پیاده شود. به دو مثال توجه کنید :

        1.  مدل حافظه مشترک بر روی یک ماشین با حافظه توزیع شده : Kendall Square Research (KSR) ALLCACHE

          حافظه ماشین از نظر فیزیکی توزیع شده است اما برای کاربر به عنوان تک حافظه مشترک ( فضای آدرس دهی سراسری ) پدیدار می شود. بطور جامع ، این نگرش به " حافظه مشترک مجازی " اشاره دارد. هر چند KSR دیگر در تجارت وجود ندارد ولی این دلیل نمی شود که بیان کنیم ترکیب هایی این چنینی در آینده توسط کمپانی دیگری به کار گرفته نشود.

        2.  مدل انتقال پیام بر روی یک ماشین حافظه مشترک : MPI on SGI Origin
          SGI Origin توسط نوع CC-NUMA از معماری حافظه مشترک به کار گرفته می شود ، جایی که هر وظیفه یا برنامه ( Task ) دسترسی مستقیم به حافظه سراسری دارد. توانایی ارسال و دریافت پیام با MPI ، که معمولا تحت شبکه ای از ماشین ها با حافظه توزیع شده انجام می شود ، بسیار مورد استفاده قرار می گیرد.

        
  • مدلی که مورد استفاده قرار می گیرد اغلب ترکیبی از آنچه موجود است و انتخاب شخصی می باشد. بهترین مدل هیچ گاه وجود ندارد ، هر چند که برخی نسبت به انواع دیگر ترکیب های بهتری هستند.

    مدل حافظه مشترک

    • در مدل برنامه نویسی موازی ، برنامه ها فضای آدرس دهی متداولی را به اشتراک می گذارند که به صورت غیر همزمان ( در زمان های مختلف ) عملیات خواندن و نوشتن را انجام می دهند.
    • مکانیزم های مختلفی همچون locks / semaphores ممکن است برای کنترل دسترسی به حافظه استفاده شود.
    • یک مزیت این مدل از دیدگاه یک برنامه نویس این است که مفهوم مالکیت اطلاعات وجود ندارد، پس نیازی نیست که صریحا ارتباطات اطلاعاتی بین برنامه ها مشخص شود. تولید یک برنامه به آسانی صورت می گیرد.
    • یکی از مهمترین معایب این مدل بر حسب عملکرد سخت تر شدن درک و مدیریت اطلاعات به صورت محلی است.
    اجرا
    • بر روی پلتفرم های حافظه مشترک ، کامپیالر محلی متغیر های برنامه کاربر را به آدرس های واقعی حافظه که سراسری است ، تبدیل می کند.
    • تاکنون هیچ اجرا بر روی پلتفرم حافظه توزیع شده موجود نیست. هر چند همانطور که در بخش های قبلی اشاره شد KSR ALLCACHE  نمایی از حافظه مشترک را ارائه می دهد در حالیکه حافظه فیزیکی ماشین توزیع شده است.

 |+| نوشته شده در  دوشنبه بیست و نهم مرداد 1386ساعت 7:20 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام

محاسبات موازی - بخش پنجم

حافظه مرکب توزیع شده - مشترک : Hybrid Distributed-Shared Memory

خلاصه ای از ویژگی های اساسی ماشین های حافظه مشترک و توزیع شده :

 

 

بزرگترین و سریعترین کامپیوتر های امروزی از هر دو معماری حافظه مشترک و توزیع شده با هم   استفاده می کنند.



بخش حافظه مشترک ، همیشه یک ماشین کش همسان SMP است. پردازنده ها بر روی یک SMP می توانند حافظه خود را به صورت سراسری آدرس دهی کنند.
بخش حافظه توزیع شده ، شبکه ای از چندین SMP است. SMP ها تنها در مورد حافظه خودشان  - نه در مورد حافظه SMP دیگر - اطلاعات دارند. بنابراین ارتباطات شبکه ای برای انتقال

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

 

 |+| نوشته شده در  دوشنبه بیست و نهم مرداد 1386ساعت 7:16 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
محاسبات موازی - بخش چهارم

معماری های حافظه برای کامپیوتر های موازی

حافظه اشتراک گذاشته شده - Shared Memory

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



   چندین پردازنده می توانند به طور مستقل عمل کنند اما منابع حافظه یکسانی را به اشتراک می گذارند.
   تغییرات در آدرسی از حافظه که بوسیله یک پردازنده صورت می گیرد برای تمام دیگر پردازنده ها قابل مشاهد است.
   ماشین های حافظه مشترک ؛ می توانند بر اساس زمان های دسترسی حافظه به دو دسته اساسی تقسیم شوند : UMA و NUMA

دستیابی یکسان به حافظه - Uniform Memory Access :
   امروزه اغلب نشان دهنده ماشین های چند پردازنده منظم  Symmetric Multiprocessor یا SMP هستند.
   پردازنده های یکسان
   دستیابی و زمان های دستیابی یکسان به حافظه
   گاهی اوقات  CC-UMA یا Cache Coherent UMA نامیده می شود. Cache Coherent یعنی اگر یک پردازنده آدرسی در حافظه مشترک را بروز رسانی کرد ، تمام دیگر پردازنده ها از این بروز رسانی آگاه شوند. Cache Coherent در سطح سخت افزار انجام می شود.

دستیابی غیر یکسان به حافظه - Non-Uniform memory Access :
   اغلب با پیوند دادن فیزیکی دو یا بیشتر SMP تشکیل می شود.
   یک SMP می تواند به طور مستقیم به حافظه SMP دیگر دسترسی داشته باشد.
   تمام پردازنده ها به تمام حافظه ها زمان دستیابی یکسان ندارند.
   دستیابی به حافظه از طریق پیوند Link آهسته تر است.
   اگر Cache Coherency بر قرار شود ، آنگاه ممکن است CC-NUMA یا Cache Coherent NUMA نیز نامیده شود.

مزایا :
   فضای آدرس دهی سراسری ، یک دور نمای برنامه نویسی کاربر پسند به حافظه را فراهم می کند.
   اشتراک داده ها بین Task ( یک برنامه یا دسته دستور العمل های شبه برنامه ) ها به دلیل مجاورت حافظه با پردازند ها سریع و یکنواخت است.

مضرات :
   اصلی ترین آن ها ، کمبود مقیاس پذیری بین حافظه و پردازند هاست. اضافه کردن CPU های بیشتر از نظر هندسی ترافیک مسیر CPU-حافظه را افزایش می دهد و برای سیستم های کش همسان ( Cache Coherent ) ترافیک مدیریت حافظه / کش را افزایش می دهد.
   مسئولیت برنامه نویس برای ساخت های همزمانی ، که آدرس دهی صحیح حافظه سراسری را تضمین کند.
   هزینه : طراحی و تولید ماشین های حافظه مشترک با افزایش تعداد پردازنده ها به طور فزاینده ای سخت و گران خواهد بود.



حافظه توزیع شده - Distributed Memory :

مشخصات عمومی :
   همچون سیستم های حافظه مشترک ، سیستم های حافظه توزیع شده متفاوتند اما یک ویژگ مشترک دارند. سیستم های حافظه توزیع شده ، برای ارتباط داخلی پردازنده - حافظه ، نیاز به یک شبکه ارتباطی دارند.



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

مزایا :
   حافظه با تغییر تعداد پردازنده ها قابل تغییر است. افزایش تعداد پردازنده ها و میزان حافظه به تناسب صورت می گیرد.
   هر پردازنده می تواند به سرعت به حافظه خودش دسترسی پیدا کند بدون مداخله و بدون ضرر ناشی از تلاش برای کش همسانی.
   بهره وری : می توان از کالا ها ، پردازنده های در دسترس و شبکه استفاده کرد.

مضرات :
   برنامه نویس مسئول بسیاری از جزئیات مرتبط با ارتباط بین پردازنده ها، می باشد.
   ممکن است با ساختار های داده کنونی که بر اساس حافظه سراسری است ، نقشه نگاری این سازماندهی حافظه مشکل باشد.
   زمان های دستیابی غیر یکسان ( NUMA ).

 

 |+| نوشته شده در  دوشنبه بیست و نهم مرداد 1386ساعت 6:49 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
محاسبات موازی - بخش سوم

مفاهیم و اصطلاحات محاسبات و برنامه نویسی موازی

معماری ون نیومن
   برای بیش از 40 سال ، تمام کامپیوتر ها از یک مدل به نام کامپیوتر ون نیومن پیروی کرده اند. که پس از ریاضیدان مجارستانی به نام جان ون نیومن، نامگذاری شده است.
   یک کامپیوتر ون نیومن از مفهوم برنامه ذخیره شده استفاده می کند. CPU یک برنامه ذخیره شده را اجرا می کند که یک سری عملیات خواندن و نوشتن روی حافظه را مشخص می کند.


   طراحی پایه :
      حافظه برای ذخیره سازی هم برنامه و هم دستور العمل ها استفاده می شود.
      دستور العمل های برنامه ، داده های کد شده ای هستند که به کامپیوتر می گوید چه کاری انجام دهد.
      داده بسادگی اطلاعاتی است که توسط برنامه استفاده می شود.
      یک واحد مرکزی پردازش ( CPU ) دستور العمل ها و داده ها را از حافظه می گیرد ، دستور العمل ها را رمز گشایی ( decode ) می کند و سپس آنها را پی در پی اجرا می کند.

طبقه بندی کلاسیک Flynn
   راه های مختلفی برای دسته بندی کامپیوتر های موازی وجود دارد. یکی از پر استفاده ترین این طبقه بندی ها که از سال 1966 تاکنون استفاده می شود طبقه بندی Flynn نام دارد. (Flynn's Taxonomy )
   طبقه بندی Flynn ، معماری کامپیوتر های چند پردازنده ای را بر اساس اینکه تا چه حدی می توانند به دو بعد مجزای دستور العمل ها  ( Instruction ) و داده ها ( Data ) دسته بندی شوند ، متمایز می کند. هر یک از این دو بعد ، تنها می توانند یکی از این دو وضعیت ممکن را داشته باشند : یگانه و تک ( Single ) یا چندگانه ( Multiple ).

   در زیر 4 طبقه بندی ممکن را بر اساس Flynn می بینید.

S I S D  :   Single Instruction, Single Data
S I M D :   Single Instruction, Multiple Data
M I S D :   Multiple Instruction, Single Data
M I M D :  Multiple Instruction, Multiple Data


تک دستور العمل ، تک داده ( SISD ) :

   یک کامپیوتر سریالی ( غیر موازی )
   تک دستور العمل : تنها یک مسیر دستور العمل ، توسط CPU در طی یک سیکل کلاک اجرا می شود.
   تک داده : تنها یک مسیر داده به عنوان ورودی در طی یک سیکل کلاک استفاده می شود.
   اجرای قطعی
   این قدیمی ترین و رایج ترین فرم یک کامپیوتر تاکنون است.
   مثال : اغلب PC ها ، پایانه های کامپیوتری و مین فریم های تک CPU


تک دستور العمل ، چندین داده ( SIMD ) :

   مدلی از یک کامپیوتر موازی
   تک دستور العمل : تمام واحد های پردازشی ، یک دستور العمل را در طی هر سیکل کلاک داده شده  ؛ اجرا می کنند.
   چندین داده : هر واحد پردازشی ، می تواند بر روی یک عنصر داده ای متفاوت عمل کند.
   این مدل از ماشین یک دستور العمل توزیع کننده ، شبکه داخلی با پهنای باند بسیار بالا و یک آرایه بسیار بزرگ از واحد های دستور العمل با ظرفیت کم ، را داراست.
   این مورد برای مسائل خاص که با سطح بالایی از نظم مشخص می شوند همچون پردازش تصویر عالی می باشد.
   اجرای قطعی و همزمان
   در دو نوع مختلف : آرایه های پردازنده ( Processor Arrays ) و کانال های برداری  ( Vector Pipelines  )
   مثال :

  Processor Arrays: Connection Machine CM-2, Maspar MP-1, MP-2
Vector Pipelines: IBM 9000, Cray C90, Fujitsu VP, NEC SX-2, Hitachi S820



چندین دستور العمل ، تک داده ( SIMD ) :

   یک تک مسیر داده ، چند واحد پردازشی را تغذیه می کند.
   هر واحد پردازشی بر روی داده ها ، مستقل و از طریق مسیر های دستور العمل مستقل عمل می کند.
   تعداد کمی از نمونه های واقعی این کلاس از کامپیوتر های موازی هنوز وجود دارد. یکی از آن ها کامپیوتر آزمایشی Carnegie-Mellon C.mmp  محصول 1971 می باشد.
   برخی کاربرد های ممکن :
      فیلتر های چند فرکانسی که بر روی تک مسیر سیگنال عمل می کنند.
      چندین الگوریتم رمز نویسی که برای شکستن رمز تک پیام کد شده استفاده می شوند.


چندین دستور العمل ، چندین داده ( MIMD ) :

   در حال حاضر متداول ترین نوع کامپیوتر های موازی هستند. اکثر کامپیوتر های مدرن در این دسته قرار می گیرند.
   چندین دستور العمل : هر پردازنده ممکن است مسیر دستور العمل متفاوتی را اجرا کند.
   چندین داده : هر پردازنده ممکن است با مسیر داده ای متفاوتی کار کند.
   اجرا می تواند همزمان و یا غیر همزمان باشد ، قطعی یا غیر قطعی.
   مثال : اکثر ابر کامپیوتر های امروزی ، کامپیوتر های موازی شبکه ای " Grids " و کامپیوتر های SMP چند پردازنده ای - شامل برخی از انواع PC ها.


برخی اصطلاحات رایج محاسبات موازی
همچون هر چیز دیگر ، محاسبات موازی زبان فنی مخصوص به خود را دارد. برخی از اصطلاحات پر کاربرد مرتبط با محاسبات موازی را در زیر می بینید.

Task
   یک بخش گسسته منطقی از عمل محساباتی. یک Task نوعا یک برنامه یا سری دستور العمل های شبیه برنامه است که توسط یک CPU اجرا می شود.

Parallel Task
   یک Task که می تواند توسط چندین پردازنده به صورت امن اجرا شود ( منجر به تولید نتایج صحیح ).

Serial Execution
   اجرای یک برنامه به صورت ترتیبی و سریالی ، یک دستور در آن واحد. چیزی که بر روی یک ماشین تک پردازنده روی می دهد. هر چند ، واقعا تمام Parallel Task ها بخش هایی از یک برنامه موازی خواهند داشت که باید سریالی اجرا شود.

Paralle Execution
   اجرای یک برنامه با بیش از یک Task ، که هر Task می تواند دستور یکسان یا متفاوتی را همزمان انجام دهد.

Shared Memory
   از یک دیدگاه شدیدا سخت افزاری ، یک معماری کامپیوتر را توصیف می کند که تمام پردازنده ها دسترسی مستقیم ( معمولا تحت باس یا گذرگاه ) به حافظه فیزیکی دارند. در مفهوم برنامه نویسی ، مدلی را توصیف می کند که تمام Parallel Task تصویری ( Picture ) یکسان از حافظه دارند و می توانند مستقیما مکان های روی حافظه را آدرس دهی کنند و به آن ها  بدون توجه به اینکه حافظه فیزیکی واقعا کجا قرار دارد ، دسترسی داشته باشند.

Distributed Memory
   در سخت افزار ، به دسترسی به حافظه تحت شبکه برای حافظه فیزیکی اشاره دارد که رایج نیست. به عنوان یک مدل برنامه نویسی ، Task ها می توانند به صورت منطقی حافظه ماشین محلی را ببینند ( See ) و باید از ارتباطاتی برای دسترسی به حافظه بر روی دیگر ماشین ها که دیگر Task ها اجرا می شوند ، استفاده کنند.

Communications
   Parallel Task ها نوعا نیاز به تبادل داده ها دارند. راه های زیادی وجود دارد که این عمل روی دهد همچون یک گذرگاه Shared Memory و یا بر روی یک شبکه ، به هر حال عمل واقعی تبادل داده بدون توجه به روش مورد استفاده ، عموما به Comminucations اشاره دارد .

Synchronization
   هماهنگی بلادرنگ Parallel Task ها ، اغلب با Communications مرتبط است و معمولا با ایجاد یک نقطه Synchronization ( همزمانی ) درون برنامه تکمیل میشود. این نقطه جایی است که ممکن است یک Task بیش از این جلو نرود تا زمانی که یک Task یا Task های دیگر  به نقطه یکسان یا از نظر منطقی برابر با آن Task نرسند.

Granularity
   در محاسبات موازی ، Granularity یک میزان کیفی از نسبت محسابات به ارتباطات است ( The Ratio of Computation to Communication ).
      Coarse : نسبتا مقادیر زیاد کار محاسباتی که بین رویداد های ارتباطی انجام شده است.
      Fine : نسبتا مقادیر کم کار محاسباتی که بین رویداد های ارتباطی انجام شده است.

Observed Speedup
   Observed Speedup ( افزایش سرعت مشاهده شده ) برای یک کد که موازی شده است ، به صورت زیر تعریف می شود :
حاصل تقسیم   wall-clock time of serial execution   بر   wall-clock time of parallel execution .
یعنی اگر زمان اجرای سریالی برنامه را بر زمان اجرای موازی آن تقسیم کنیم ؛ حاصل نشان دهنده " افزایش سرعت مشاهده شده " می باشد. روش فوق یکی از پر کاربرد ترین شاخص های کارایی برنامه موازی می باشد.

Parallel Overhead
   مقدار زمان مورد نیاز برای هماهنگ سازی Parallel Task  ها ، در مقابل انجام کار مفید. Parallel Overhead می تواند فاکتور های زیر را دارا باشد :
      زمان راه اندازی Task
      همزمان سازی - Synchronizations
      ارتباطات داده ها
      پردازش نرم افزار اعمال شده توسط کامپیالر های موازی ، کتابخانه ها ، ابزار ها ، سیستم عامل و ...

Massively Parallel
   به سخت افزاری اشاره دارد که شامل سیستم موازی داده شده است - پردازندها های زیادی دارد. معنی زیاد در اینجا فزاینده و افزایشی است ، که اکنون BG/L ( ابر کامپیوتر بلوجین که قویترین ابر کامپیوتر حال حاضر دنیاست ) این تعداد را تا 6 رقم به جلو برده است.

Scalability
   به توانایی سیستم ( سخت افزار و / یا نرم افزار )  های موازی برای نمایش یک افزایش متناسب در تسریع موازی ( Parallel Speedup ) با افزایش پردازنده های بیشتر اشاره دارد. فاکتور هایی در Scalability  ( مقیاس پذیری ) نقش دارند :
      سخت افزار - به خصوص پهنای باند حافظه و CPU و ارتباطات شبکه
      الگوریتم برنامه
      Parallel Overhead مرتبط
      ویژگی های خاص برنامه نویسی و برنامه شما

در مقاله بعدی به انواع مدل های حافظه می پردازیم.

 |+| نوشته شده در  دوشنبه بیست و نهم مرداد 1386ساعت 6:46 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
محاسبات موازی - بخش دوم

چرا از محاسبات موازی استفاده کنیم ؟

دلایل اصلی استفاده از محاسبات موازی :

   صرفه جویی در زمان
   حل مسائل بزرگتر و عظیم تر
   فراهم کردن همزمانی ( انجام چند عمل به صورت همزمان )

دیگر دلایلی که ممکن است وجود داشته باشد :

   بهره مندی از مزایای منابع غیر محلی - استفاده از منابع محاسباتی در دسترس بر روی یک شبکه گسترده و یا حتی اینترنت ، زمانی که منابع محاسباتی محلی اندک باشند
   صرفه جویی در هزینه - استفاده از چند منابع محاسباتی ارزان به جای هزینه کردن برای یک ابر کامپیوتر
   غلبه بر محدودیت های حافظه - یک کامپیوتر منابع حافظه بسیار محدودی دارد. برای مسائل عظیم تر ؛ استفاده از حافظه های چندین کامپیوتر می تواند این مشکل را برطرف کند.

محدودیت های محاسباتی سریالی

دلایل فیزیکی و عملی  محدودیت های مهمی برای ساخت سریعترین کامپیوتر های سریالی ایجاد می کنند :
   سرعت های عبور - سرعت یک کامپیوتر سریالی مستقیما به اینکه اطلاعات چقدر سریع از طریق سخت افزار ها منتقل می شوند ، بستگی دارد. محدودیت مطلق سرعت نور است ( 30 سانتیمتر در نانو ثانیه ) و محدودیت انتقال سیم مسی ( 9 سانتیمتر در نانو ثانیه ) . سرعت های صعودی ، همزمان ، توسعه و افزایش عناصر پردازنده را ایجاب می کنند.
   محدودیت های کوچک سازی  - فناوری پردازنده ها یک تعداد صعودی از ترانزیستور ها را مجاز می کند که بر روی یک چیپ قرار بگیرند. به هر حال ، با وجود اجزای مولکولی و ذره ای ، محدودیتی وجود دارد که اجزا چقدر می توانند کوچک شوند.
   محدودیت های اقتصادی -  سریعتر کردن یک تک پردازنده به طور فزاینده ای هزینه بر است. استفاده از تعداد زیادی پردازنده با سرعت میانه برای دست یابی به همان کارایی ( و حتی بهتر ) هزینه کمتری دارد.

آینده : طی 10 سال گذشته ، گرایش به شبکه های سریعتر ، سیستم های توزیعی ، معماری کامپیوتر چند پردازنده ای ( حتی در سطح
کامپیوتر های رومیزی ) به وضوح نشان می دهد که توازی یا موازی نگری ( Parallelism ) آینده محاسبات می باشد.

چه کسی و چه چیزی ؟

Top500.org آمازی از کاربران محاسبات موازی ارائه می دهد - نمودار های زیر تنها یک نمونه هستند. نکاتی که درباره نمودار زیر باید توجه شوند :
   بخش های نمودار زیر ممکن است اشتراک داشته باشند- برای مثال ، تحقیق ممکن است تحقیق طبقه بندی شده ، باشد.
   تعیین نشده "Not Specified"  بمراتب بزرگترین برنامه است. - احتمالا به معنی چندین برنامه است.



در مقاله بعدی به "مفاهیم و اصطلاحات محاسبات و برنامه نویسی موازی" می پردازیم.

 

 |+| نوشته شده در  دوشنبه بیست و نهم مرداد 1386ساعت 6:40 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
محاسبات موازی - بخش اول

محاسبات موازی یا Parallel Computing چیست ؟
در گذشته ، نرم افزار برای محاسبات سریال ( نوبتی ) نوشته می شده است :
  برای اجرا بر روی کامپیوتری که تنها یک واحد مرکزی پردازش CPU دارد .
  یک مسئله به سری هایی مجزا از دستور العمل ها تقسیم می شود.
  دستور العمل ها یکی پس از دیگری اجرا می شود.
  تنها یک دستور العمل در هر لحظه می تواند اجرا شود.






به ساده ترین معنی ، محاسبات موازی استفاده همزمان از چند منبع محاسباتی برای        حل  یک مساله محاسباتی می باشد.
   برای اجرا با استفاده از چند CPU
   یک مسله به چند بخش تقسیم می شود ؛ به نحوی که بتوان آن قسمت ها را همزمان ( با هم )   حل کرد.
   هر بخش نیز به سری از دستور العمل ها تقسیم می شود.
   دستور العمل های هر بخش همزمان بر روی CPU های مختلف اجرا می شود.



منبع محاسباتی می تواند شامل موارد زیر باشد :
   یک کامپیوتر با چند پردازنده
   تعدادی کامپیوتر که با شبکه با یکدیگر متصل شده اند.
   ترکیبی از هر دو

مسئله محاسباتی ویژگی هایی را نشان می دهد که آیا توانایی موارد زیر دارد یا نه :
   شکسته شدن به بخش های مجزا که بتوان همزمان آن ها را اجرا کرد.
   اجرا کردن چندین دستور العمل برنامه در هر لحظه ( اجرای یک دستور العمل در هر لحظه از ویژگی های محاسبات سریال بود )
   حل شدن مساله در زمان کمتر با چندین منبع محاسباتی نسبت به استفاده از یک منبع محاسباتی

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

به صورت عادی ، محاسبات موازی به عنوان " نقطه اوج محاسبات " مطرح شده است و با شبیه سازی عددی سیستم های پیچیده
و مسائل چالش بر انگیز به حرکت در آمده است :

   آب و هوا و اقلیم
   واکنش های شیمیایی و هسته ای
   ژنوم زیستی انسان
   فعالیت های زمین لرزه ای و زمین شناختی
   دستگاه های مکانیکی - از پروتز ها تا سفینه های فضایی
   مدار های الکترونیکی
   فرآیند های تولیدی

امروزه ، برنامه های تجاری نیروی محرکه ای برای تولید و توسعه کامپیوتر های سریعتر فراهم کرده اند. این برنامه ها نیاز به پردازش مقادیر بیشتر اطلاعات در مسیر های پیچیده دارند. نمونه هایی از این برنامه ها عبارتند از :
   بانک های اطلاعاتی موازی ، استخراج داده ها
   اکتشاف نفت
   موتور های جستجوی وب ، سرویس های تجاری تحت وب
   تشخیص های پزشکی به کمک کامپیوتر
   مدیریت شرکت های ملی و چند ملیتی
   گرافیک پیشرفته و واقعیت مجازی ، به ویژه در صنعت سرگرمی
   محیط های کار اشتراکی ( تعاونی )

سرانجام ، محاسبات موازی تلاشی است برای بیشینه سازی و افزایش متاعی نادر به نام زمان .

در مقاله بعدی به این سوال که " چرا از محاسبات موازی استفاده کنیم ؟ " پاسخ خواهیم داد.

 

 |+| نوشته شده در  دوشنبه بیست و نهم مرداد 1386ساعت 6:29 بعد از ظهر  توسط حامد سلیمی پور  |  داغ کن - کلوب دات کام
 
  بالا