diff --git a/.translate/state/need_for_speed.md.yml b/.translate/state/need_for_speed.md.yml index cd79acb..c9970c5 100644 --- a/.translate/state/need_for_speed.md.yml +++ b/.translate/state/need_for_speed.md.yml @@ -1,6 +1,6 @@ -source-sha: cc9c3256dc35bd277cb25d0089f0a0452c0fa94e -synced-at: "2026-03-20" -model: unknown -mode: RESYNC +source-sha: 21f1ea0669031ccc0ee0194878439a87de5d248d +synced-at: "2026-04-10" +model: claude-sonnet-4-6 +mode: UPDATE section-count: 5 -tool-version: 0.13.1 +tool-version: 0.14.1 diff --git a/.translate/state/numba.md.yml b/.translate/state/numba.md.yml index a0e2570..d5a9787 100644 --- a/.translate/state/numba.md.yml +++ b/.translate/state/numba.md.yml @@ -1,6 +1,6 @@ -source-sha: ab53ebc3d56705b836f0ca8207d70d1ff3ba0936 -synced-at: "2026-04-09" +source-sha: 21f1ea0669031ccc0ee0194878439a87de5d248d +synced-at: "2026-04-10" model: claude-sonnet-4-6 mode: UPDATE section-count: 7 -tool-version: 0.14.0 +tool-version: 0.14.1 diff --git a/lectures/need_for_speed.md b/lectures/need_for_speed.md index 9434995..320aaa3 100644 --- a/lectures/need_for_speed.md +++ b/lectures/need_for_speed.md @@ -59,7 +59,7 @@ translation: ## مرور کلی -احتمالاً می‌توان با اطمینان گفت که پایتون محبوب‌ترین زبان برای محاسبات علمی است. +پایتون محبوب‌ترین زبان برای بسیاری از جنبه‌های محاسبات علمی است. این به دلیل موارد زیر است: @@ -98,35 +98,36 @@ import matplotlib.pyplot as plt import random ``` - ## کتابخانه‌های علمی اصلی بیایید به طور خلاصه کتابخانه‌های علمی پایتون را مرور کنیم. - ### چرا به آنها نیاز داریم؟ -یکی از دلایل استفاده از کتابخانه‌های علمی این است که آنها روال‌هایی را که می‌خواهیم استفاده کنیم، پیاده‌سازی می‌کنند. +ما به کتابخانه‌های علمی پایتون به دو دلیل نیاز داریم: -* انتگرال‌گیری عددی، درونیابی، جبر خطی، یافتن ریشه و غیره. +1. پایتون کوچک است +2. پایتون کند است -به عنوان مثال، معمولاً بهتر است از یک روال موجود برای یافتن ریشه استفاده کنیم تا اینکه از ابتدا یک روال جدید بنویسیم. +**پایتون کوچک است** -(برای الگوریتم‌های استاندارد، کارایی زمانی به حداکثر می‌رسد که جامعه بتواند در یک مجموعه مشترک از پیاده‌سازی‌ها هماهنگ شود، که توسط متخصصان نوشته شده و توسط کاربران برای سریع و قوی بودن تا حد ممکن تنظیم شده‌اند!) +هسته پایتون به طور عمدی کوچک طراحی شده است -- این به بهینه‌سازی، دسترسی‌پذیری و نگهداری کمک می‌کند. -اما این تنها دلیلی نیست که ما از کتابخانه‌های علمی پایتون استفاده می‌کنیم. +کتابخانه‌های علمی روال‌هایی را فراهم می‌کنند که نمی‌خواهیم -- و احتمالاً نباید -- خودمان بنویسیم. -دلیل دیگر این است که پایتون خالص سریع نیست. +* انتگرال‌گیری عددی، درونیابی، جبر خطی، یافتن ریشه و غیره. -بنابراین به کتابخانه‌هایی نیاز داریم که برای تسریع اجرای کد پایتون طراحی شده‌اند. +**پایتون کند است** -آنها این کار را با استفاده از دو استراتژی انجام می‌دهند: +دلیل دیگری که به کتابخانه‌های علمی نیاز داریم این است که پایتون خالص نسبتاً کند است. -1. استفاده از کامپایلرهایی که دستورات شبیه پایتون را به کد ماشین سریع برای رشته‌های منفرد منطقی تبدیل می‌کنند و -2. موازی‌سازی وظایف در چندین "کارگر" (به عنوان مثال، CPUها، رشته‌های منفرد داخل GPUها). +کتابخانه‌های علمی اجرا را با استفاده از سه استراتژی اصلی تسریع می‌کنند: -ما این ایده‌ها را به طور گسترده در این سخنرانی و سخنرانی‌های باقی‌مانده این مجموعه بحث خواهیم کرد. +1. برداری‌سازی: فراهم کردن کد ماشین کامپایل‌شده و رابط‌هایی که این کد را قابل دسترس می‌کنند +1. کامپایل JIT: کامپایلرهایی که دستورات شبیه پایتون را در زمان اجرا به کد ماشین سریع تبدیل می‌کنند +2. موازی‌سازی: توزیع وظایف در چندین thread / CPU / GPU / TPU +ما این ایده‌ها را در ادامه به تفصیل بحث خواهیم کرد. ### اکوسیستم علمی پایتون @@ -148,8 +149,7 @@ import random * Pandas انواع و توابعی را برای دستکاری داده‌ها فراهم می‌کند. * Numba یک کامپایلر just-in-time فراهم می‌کند که با NumPy به خوبی کار می‌کند و به تسریع کد پایتون کمک می‌کند. -ما همه این کتابخانه‌ها را به طور گسترده در این مجموعه سخنرانی‌ها مورد بحث قرار خواهیم داد. - +ما همه این کتابخانه‌ها را به تفصیل در این مجموعه درس‌ها مورد بحث قرار خواهیم داد. ## پایتون خالص کند است @@ -159,7 +159,6 @@ import random برای این موضوع، مفید خواهد بود اگر درک کنیم که چه چیزی باعث سرعت اجرای کند می‌شود. - ### کد سطح بالا در مقابل سطح پایین زبان‌های سطح بالاتر مانند پایتون برای انسان‌ها بهینه شده‌اند. @@ -176,12 +175,10 @@ import random از طرف دیگر، پیاده‌سازی استاندارد پایتون (به نام CPython) نمی‌تواند با سرعت زبان‌های کامپایل شده مانند C یا Fortran برابری کند. - ### گلوگاه‌ها کجا هستند؟ چرا اینطور است؟ - #### تایپ کردن پویا ```{index} single: Dynamic Typing @@ -212,14 +209,11 @@ a, b = ['foo'], ['bar'] a + b ``` -(ما می‌گوییم که عملگر `+` *بارگذاری شده* است --- عمل آن به نوع اشیایی که بر روی آنها عمل می‌کند بستگی دارد) - در نتیجه، هنگام اجرای `a + b`، پایتون ابتدا باید نوع اشیا را بررسی کند و سپس عملیات صحیح را فراخوانی کند. -این شامل یک سربار غیر قابل اغماض است. - -اگر ما بارها و بارها این عبارت را در یک حلقه تنگ اجرا کنیم، سربار غیر قابل اغماض به یک سربار بزرگ تبدیل می‌شود. +این شامل سربار می‌شود. +اگر ما بارها و بارها این عبارت را در یک حلقه تنگ اجرا کنیم، سربار بزرگ می‌شود. #### انواع ایستا @@ -254,7 +248,6 @@ int main(void) { نیازی به بررسی نوع نیست و بنابراین سربار وجود ندارد. - ### دسترسی به داده یکی دیگر از موانع سرعت برای زبان‌های سطح بالا، دسترسی به داده است. @@ -263,22 +256,15 @@ int main(void) { #### جمع کردن با کد کامپایل شده -در C یا Fortran، این اعداد صحیح معمولاً در یک آرایه ذخیره می‌شوند که یک ساختار داده ساده برای ذخیره داده‌های همگن است. - -چنین آرایه‌ای در یک بلوک پیوسته واحد از حافظه ذخیره می‌شود: +در C یا Fortran، یک آرایه از اعداد صحیح در یک بلوک پیوسته واحد از حافظه ذخیره می‌شود: -* در کامپیوترهای مدرن، آدرس‌های حافظه به هر بایت اختصاص داده می‌شوند (یک بایت = 8 بیت). * به عنوان مثال، یک عدد صحیح 64 بیتی در 8 بایت حافظه ذخیره می‌شود. * یک آرایه از $n$ چنین اعداد صحیحی $8n$ شکاف حافظه *متوالی* اشغال می‌کند. -علاوه بر این، کامپایلر توسط برنامه‌نویس از نوع داده آگاه می‌شود. - -* در این مورد اعداد صحیح 64 بیتی +علاوه بر این، نوع داده در زمان کامپایل مشخص است. از این رو، هر نقطه داده متوالی می‌تواند با جابجایی رو به جلو در فضای حافظه به میزان مشخص و ثابتی دسترسی پیدا کند. -* در این مورد 8 بایت - #### جمع کردن در پایتون خالص پایتون سعی می‌کند این ایده‌ها را تا حدی تکرار کند. @@ -289,11 +275,7 @@ int main(void) { از این رو، هنوز سربار در دسترسی به خود مقادیر داده وجود دارد. -این یک مانع قابل توجه بر سرعت است. - -در واقع، به طور کلی درست است که ترافیک حافظه یک مجرم اصلی است وقتی صحبت از اجرای کند می‌شود. - - +چنین سرباری یک مجرم اصلی است وقتی صحبت از اجرای کند می‌شود. ### خلاصه @@ -311,11 +293,6 @@ int main(void) { این کار بهترین است که به کامپایلرهای تخصصی واگذار شود! -برخی از کتابخانه‌های پایتون قابلیت‌های برجسته‌ای برای موازی‌سازی کد علمی دارند -- ما در ادامه بیشتر در این مورد بحث خواهیم کرد. - - - - ## تسریع پایتون در این بخش به سه تکنیک مرتبط برای تسریع کد پایتون نگاه می‌کنیم. @@ -324,8 +301,6 @@ int main(void) { بعداً به کتابخانه‌های خاص و نحوه پیاده‌سازی این ایده‌ها توسط آنها نگاه خواهیم کرد. - - ### {index}`برداری‌سازی ` ```{index} single: Python; Vectorization @@ -356,7 +331,7 @@ int main(void) { ```{figure} /_static/lecture_specific/need_for_speed/matlab.png ``` - +NumPy از مدلی مشابه استفاده می‌کند که از MATLAB الهام گرفته است. ### برداری‌سازی در مقابل حلقه‌های پایتون خالص @@ -414,50 +389,39 @@ with qe.Timer(): در سخنرانی‌های بعدی در این مجموعه، در مورد چگونگی بهره‌برداری کتابخانه‌های مدرن پایتون از کامپایلرهای just-in-time برای تولید کد ماشین سریع، کارآمد و موازی یاد خواهیم گرفت. - - - ## موازی‌سازی رشد سرعت کلاک CPU (یعنی سرعتی که یک زنجیره منفرد منطقی می‌تواند اجرا شود) در سال‌های اخیر به طور چشمگیری کند شده است. طراحان تراشه و برنامه‌نویسان کامپیوتر با کندی با جستجوی مسیری متفاوت برای اجرای سریع پاسخ داده‌اند: موازی‌سازی. -سازندگان سخت‌افزار تعداد هسته‌ها (CPUهای فیزیکی) تعبیه شده در هر ماشین را افزایش داده‌اند. - -برای برنامه‌نویسان، چالش این بوده است که از این CPUهای چندگانه با اجرای بسیاری از فرآیندها به صورت موازی (یعنی همزمان) بهره‌برداری کنند. +این شامل موارد زیر می‌شود: -این امر به ویژه در برنامه‌نویسی علمی مهم است که نیاز به مدیریت موارد زیر دارد: +1. افزایش تعداد CPUهای تعبیه شده در هر ماشین +1. اتصال شتاب‌دهنده‌های سخت‌افزاری مانند GPUها و TPUها -* مقادیر زیادی از داده‌ها و -* شبیه‌سازی‌های فشرده CPU و سایر محاسبات. +برای برنامه‌نویسان، چالش این بوده است که از این سخت‌افزار با اجرای بسیاری از فرآیندها به صورت موازی بهره‌برداری کنند. در زیر ما موازی‌سازی برای محاسبات علمی را با تمرکز بر موارد زیر بحث می‌کنیم: -1. بهترین ابزارها برای موازی‌سازی در پایتون و +1. ابزارهای موازی‌سازی در پایتون و 1. چگونه این ابزارها می‌توانند برای مسائل اقتصادی کمی به کار گرفته شوند. - ### موازی‌سازی بر روی CPUها بیایید دو نوع اصلی موازی‌سازی مبتنی بر CPU که معمولاً در محاسبات علمی استفاده می‌شود را مرور کنیم و مزایا و معایب آنها را بحث کنیم. - #### چندپردازشی -چندپردازشی به معنای اجرای همزمان چندین فرآیند با استفاده از بیش از یک پردازنده است. - -در این زمینه، یک **فرآیند** یک زنجیره از دستورات (یعنی یک برنامه) است. +چندپردازشی به معنای اجرای همزمان چندین رشته منطقی با استفاده از بیش از یک پردازنده است. -چندپردازشی می‌تواند روی یک ماشین با CPUهای چندگانه یا روی مجموعه‌ای از ماشین‌های متصل شده توسط یک شبکه انجام شود. +چندپردازشی می‌تواند روی یک ماشین با CPUهای چندگانه یا روی کلاستری از ماشین‌های متصل شده توسط یک شبکه انجام شود. -در مورد دوم، مجموعه ماشین‌ها معمولاً **کلاستر** نامیده می‌شود. - -با چندپردازشی، هر فرآیند فضای حافظه خود را دارد، اگرچه تراشه حافظه فیزیکی ممکن است مشترک باشد. +با چندپردازشی، *هر فرآیند فضای حافظه خود را دارد*، اگرچه تراشه حافظه فیزیکی ممکن است مشترک باشد. #### چندرشته‌ای -چندرشته‌ای شبیه به چندپردازشی است، به جز اینکه، در طول اجرا، همه رشته‌ها فضای حافظه یکسانی را به اشتراک می‌گذارند. +چندرشته‌ای شبیه به چندپردازشی است، به جز اینکه، در طول اجرا، همه رشته‌ها *فضای حافظه یکسانی را به اشتراک می‌گذارند*. پایتون بومی برای پیاده‌سازی چندرشته‌ای به دلیل برخی [ویژگی‌های طراحی قدیمی](https://wiki.python.org/moin/GlobalInterpreterLock) مشکل دارد. @@ -475,7 +439,6 @@ with qe.Timer(): برای اکثریت قریب به اتفاق کاری که ما در این سخنرانی‌ها انجام می‌دهیم، چندرشته‌ای کافی خواهد بود. - ### شتاب‌دهنده‌های سخت‌افزاری در حالی که CPUها با هسته‌های چندگانه برای محاسبات موازی استاندارد شده‌اند، یک تغییر چشمگیرتر با ظهور شتاب‌دهنده‌های سخت‌افزاری تخصصی رخ داده است. @@ -501,7 +464,6 @@ TPUها یک توسعه اخیرتر هستند که توسط گوگل به طو مانند GPUها، TPUها در انجام تعداد عظیمی از عملیات ماتریسی به صورت موازی عالی هستند. - #### چرا TPU/GPU مهم هستند دستاوردهای عملکردی از استفاده از شتاب‌دهنده‌های سخت‌افزاری می‌تواند چشمگیر باشد. @@ -512,7 +474,6 @@ TPUها یک توسعه اخیرتر هستند که توسط گوگل به طو این امر به ویژه برای محاسبات علمی مرتبط است زیرا بسیاری از الگوریتم‌ها به طور طبیعی بر روی معماری موازی GPUها نگاشت می‌شوند. - ### GPUهای تکی در مقابل سرورهای GPU دو روش رایج برای دسترسی به منابع GPU وجود دارد: @@ -527,7 +488,6 @@ TPUها یک توسعه اخیرتر هستند که توسط گوگل به طو کتابخانه‌های مدرن پایتون مانند JAX که به طور گسترده در این مجموعه سخنرانی‌ها مورد بحث قرار می‌گیرند، به طور خودکار GPUهای موجود را با تغییرات حداقلی در کد تشخیص داده و استفاده می‌کنند. - #### سرورهای چند GPU برای مسائل در مقیاس بزرگتر، سرورهای حاوی GPUهای متعدد (اغلب 4-8 GPU در هر سرور) به طور فزاینده‌ای رایج هستند. @@ -540,11 +500,10 @@ TPUها یک توسعه اخیرتر هستند که توسط گوگل به طو این محققان را قادر می‌سازد مسائلی را که بر روی یک GPU یا CPU تکی غیرعملی هستند، مورد بررسی قرار دهند. - ### خلاصه محاسبات GPU بسیار در دسترس‌تر می‌شود، به ویژه از داخل پایتون. برخی از کتابخانه‌های علمی پایتون، مانند JAX، اکنون شتاب GPU را با تغییرات حداقلی در کد موجود پشتیبانی می‌کنند. -ما محاسبات GPU را با جزئیات بیشتری در سخنرانی‌های بعدی بررسی خواهیم کرد و آن را در طیف وسیعی از کاربردهای اقتصادی به کار خواهیم برد. \ No newline at end of file +ما محاسبات GPU را با جزئیات بیشتری در سخنرانی‌های بعدی بررسی خواهیم کرد و آن را در طیف وسیعی از کاربردهای اقتصادی به کار خواهیم برد. diff --git a/lectures/numba.md b/lectures/numba.md index 913ee7e..6b6e39c 100644 --- a/lectures/numba.md +++ b/lectures/numba.md @@ -21,7 +21,6 @@ translation: Dangers and Limitations: خطرات و محدودیت‌ها Dangers and Limitations::Limitations: محدودیت‌ها 'Dangers and Limitations::A Gotcha: Global Variables': 'یک مشکل: متغیرهای سراسری' - Dangers and Limitations::Caching Compiled Code: ذخیره‌سازی کد کامپایل‌شده Multithreaded Loops in Numba: حلقه‌های چندنخی در Numba Exercises: تمرین‌ها --- @@ -60,9 +59,11 @@ import matplotlib.pyplot as plt در یک {doc}`درس قبلی ` درباره برداری‌سازی بحث کردیم، که می‌تواند سرعت اجرا را با ارسال دسته‌ای عملیات پردازش آرایه به کد کارآمد سطح پایین بهبود بخشد. -با این حال، همانطور که {ref}`قبلاً بحث شد `، طرح‌های سنتی برداری‌سازی، مانند آنچه در MATLAB، Julia و NumPy یافت می‌شود، چندین نقطه ضعف دارند. +با این حال، همانطور که {ref}`در آن درس بحث شد `، +طرح‌های سنتی برداری‌سازی، مانند آنچه در MATLAB، Julia و NumPy یافت می‌شود، نقاط ضعفی دارند. -برای مثال، می‌توانند بسیار حافظه‌بر باشند و برای برخی الگوریتم‌ها، برداری‌سازی ناکارآمد یا غیرممکن است. +* برای عملیات ترکیبی آرایه‌ها بسیار حافظه‌بر هستند +* برای برخی الگوریتم‌ها ناکارآمد یا غیرممکن است. یک راه برای دور زدن این مشکلات، استفاده از [Numba](https://numba.pydata.org/) است، یک **کامپایلر در زمان اجرا (JIT)** برای Python که به سمت کار عددی جهت‌گیری شده است. @@ -74,6 +75,14 @@ Numba توابع را در حین اجرا به دستورالعمل‌های ک علاوه بر این، Numba می‌تواند ترفندهای مفید دیگری نیز انجام دهد، مانند {ref}`چندنخی ` یا ارتباط با GPU‌ها (از طریق `numba.cuda`). +کامپایلر JIT نامبا از بسیاری جهات مشابه کامپایلر JIT در JULIA است. + +تفاوت اصلی در این است که کمتر جاه‌طلبانه است و تلاش می‌کند زیرمجموعه کوچک‌تری از زبان را کامپایل کند. + +اگرچه این ممکن است مانند یک نقص به نظر برسد، اما از برخی جهات یک مزیت محسوب می‌شود. + +Numba سبک، آسان برای استفاده و بسیار خوب در آنچه انجام می‌دهد است. + این درس ایده‌های اصلی را معرفی می‌کند. (numba_link)= @@ -86,9 +95,9 @@ Numba توابع را در حین اجرا به دستورالعمل‌های ک (quad_map_eg)= ### یک مثال -بیایید مسئله‌ای را در نظر بگیریم که برداری‌سازی آن دشوار است: تولید مسیر یک معادله تفاضلی با توجه به یک شرط اولیه. +بیایید مسئله‌ای را در نظر بگیریم که برداری‌سازی آن دشوار است (یعنی واگذاری آن به عملیات پردازش آرایه). -معادله تفاضلی را نگاشت درجه دوم در نظر می‌گیریم: +این مسئله شامل تولید مسیر از طریق نگاشت درجه دوم است: $$ x_{t+1} = \alpha x_t (1 - x_t) @@ -176,10 +185,10 @@ Numba تلاش می‌کند با استفاده از زیرساختی که [پ * پایتون بسیار انعطاف‌پذیر است و از این رو می‌توانیم تابع qm را با انواع مختلفی فراخوانی کنیم. * مثلاً `x0` می‌تواند یک آرایه NumPy یا یک لیست باشد، `n` می‌تواند یک عدد صحیح یا یک عدد اعشاری باشد و غیره. -* این امر *پیش*-کامپایل کردن تابع (یعنی کامپایل پیش از زمان اجرا) را دشوار می‌سازد. -* اما وقتی واقعاً تابع را فراخوانی می‌کنیم، مثلاً با اجرای `qm(0.5, 10)`، انواع `x0` و `n` مشخص می‌شوند. +* این امر تولید کد ماشین کارآمد *پیش از زمان اجرا* را بسیار دشوار می‌سازد. +* اما وقتی واقعاً تابع را *فراخوانی* می‌کنیم، مثلاً با اجرای `qm(0.5, 10)`، انواع `x0` و `n` مشخص می‌شوند. * علاوه بر این، انواع *سایر متغیرها* در `qm` *می‌توانند پس از مشخص شدن انواع ورودی استنتاج شوند*. -* بنابراین استراتژی Numba و سایر کامپایلرهای JIT این است که تا این لحظه صبر کنند و سپس تابع را کامپایل کنند. +* بنابراین استراتژی Numba و سایر کامپایلرهای JIT این است که *تا زمان فراخوانی تابع صبر کنند* و سپس کامپایل کنند. به همین دلیل است که به آن کامپایل «درست به موقع» (just-in-time) گفته می‌شود. @@ -241,14 +250,10 @@ Numba همچنین با آرایه‌های NumPy که انواع به خوبی در یک محیط ایده‌آل، Numba می‌تواند تمام اطلاعات نوع لازم را استنتاج کند. -این به آن اجازه می‌دهد تا کد ماشین بومی تولید کند، بدون نیاز به فراخوانی محیط زمان اجرای Python. +این به آن اجازه می‌دهد تا کد ماشین بومی کارآمدی تولید کند، بدون نیاز به فراخوانی محیط زمان اجرای Python. وقتی Numba نمی‌تواند تمام اطلاعات نوع را استنتاج کند، خطا ایجاد می‌کند. -```{note} -در نسخه‌های قدیمی‌تر Numba، دکوراتور `@jit` در صورت عدم توانایی در استنتاج همه انواع، به آرامی به «حالت شیء» بازمی‌گشت که سرعت چندانی به همراه نداشت. نسخه‌های فعلی Numba به طور پیش‌فرض از حالت `nopython` استفاده می‌کنند، به این معنا که کامپایلر بر استنتاج کامل نوع اصرار دارد و در صورت شکست، خطا ایجاد می‌کند. اغلب در کدهای دیگر `@njit` را می‌بینید که صرفاً یک نام مستعار برای `@jit(nopython=True)` است. از آنجا که حالت nopython اکنون پیش‌فرض است، `@jit` و `@njit` معادل یکدیگرند. -``` - به عنوان مثال، در تنظیم (مصنوعی) زیر، Numba قادر به تعیین نوع تابع `mean` هنگام کامپایل تابع `bootstrap` نیست ```{code-cell} ipython3 @@ -294,9 +299,7 @@ with qe.Timer(): همانطور که دیدیم، Numba باید اطلاعات نوع را روی تمام متغیرها استنتاج کند تا دستورالعمل‌های سریع سطح ماشین تولید کند. -برای روال‌های ساده، Numba انواع را بسیار خوب استنتاج می‌کند. - -برای روال‌های بزرگتر، یا برای روال‌هایی که از کتابخانه‌های خارجی استفاده می‌کنند، به راحتی می‌تواند شکست بخورد. +برای روال‌های بزرگ یا روال‌هایی که از کتابخانه‌های خارجی استفاده می‌کنند، این فرایند به راحتی می‌تواند شکست بخورد. از این رو، بهتر است روی تسریع قطعات کوچک و حیاتی کد تمرکز کنید. @@ -328,30 +331,12 @@ print(add_a(10)) وقتی Numba کد ماشین را برای توابع کامپایل می‌کند، متغیرهای سراسری را به عنوان ثابت برای اطمینان از پایداری نوع درمان می‌کند. -### ذخیره‌سازی کد کامپایل‌شده - -به طور پیش‌فرض، Numba در هر بار شروع یک نشست Python جدید، توابع را مجدداً کامپایل می‌کند. - -برای جلوگیری از این سربار، می‌توانید `cache=True` را به دکوراتور ارسال کنید: - -```{code-cell} ipython3 -@jit(cache=True) -def qm(x0, n): - x = np.empty(n+1) - x[0] = x0 - for t in range(n): - x[t+1] = α * x[t] * (1 - x[t]) - return x -``` - -این کد کامپایل‌شده را روی دیسک ذخیره می‌کند تا نشست‌های بعدی بتوانند از مرحله کامپایل صرف‌نظر کنند. - (multithreading)= ## حلقه‌های چندنخی در Numba -علاوه بر کامپایل JIT، Numba پشتیبانی از محاسبات موازی در CPUها ارائه می‌دهد. +علاوه بر کامپایل JIT، Numba پشتیبانی از محاسبات موازی در CPUها و GPUها ارائه می‌دهد. -ابزار کلیدی برای موازی‌سازی در Numba تابع `prange` است که به Numba می‌گوید تا تکرارهای حلقه را به صورت موازی در هسته‌های CPU موجود اجرا کند. +ابزار کلیدی برای موازی‌سازی در CPUها در Numba تابع `prange` است که به Numba می‌گوید تا تکرارهای حلقه را به صورت موازی در هسته‌های موجود اجرا کند. برای نمایش، ابتدا به یک قطعه کد ساده تک‌نخی (یعنی غیرموازی) نگاه می‌کنیم. @@ -408,24 +393,10 @@ plt.show() حالا فرض کنیم که جمعیت زیادی از خانوارها داریم و می‌خواهیم بدانیم میانه ثروت چه خواهد بود. -حل این موضوع با مداد و کاغذ آسان نیست، بنابراین به جای آن از شبیه‌سازی استفاده خواهیم کرد. - -به طور خاص، تعداد زیادی از خانوارها را شبیه‌سازی می‌کنیم و سپس میانه ثروت را برای این گروه محاسبه می‌کنیم. +حل این موضوع با مداد و کاغذ آسان نیست، بنابراین به جای آن از شبیه‌سازی استفاده خواهیم کرد: -فرض کنیم به میانگین بلندمدت این میانه در طول زمان علاقه‌مند هستیم. - -برای مشخصاتی که در بالا انتخاب کرده‌ایم، می‌توانیم این را با گرفتن یک مقطع عرضی یک دوره‌ای از میانه ثروت گروه در پایان یک شبیه‌سازی طولانی محاسبه کنیم. - -علاوه بر این، به شرطی که دوره شبیه‌سازی به اندازه کافی طولانی باشد، شرایط اولیه اهمیتی ندارند. - -(این به دلیل [ارگودیسیته](https://python.quantecon.org/finite_markov.html#id15) است.) - -بنابراین، به طور خلاصه، قصد داریم 50,000 خانوار را شبیه‌سازی کنیم با - -1. تنظیم خودسرانه ثروت اولیه به 1 و -1. شبیه‌سازی رو به جلو در زمان برای 1,000 دوره. - -سپس میانه ثروت را در پایان دوره محاسبه خواهیم کرد. +1. تعداد زیادی از خانوارها را در طول زمان شبیه‌سازی می‌کنیم +2. میانه ثروت را محاسبه می‌کنیم در اینجا کد است: @@ -479,6 +450,8 @@ with qe.Timer(): افزایش سرعت قابل توجه است. +توجه داشته باشید که موازی‌سازی را در سطح خانوارها انجام می‌دهیم نه در طول زمان -- به‌روزرسانی‌های یک خانوار در دوره‌های زمانی مختلف ذاتاً ترتیبی هستند. + ## تمرین‌ها ```{exercise} @@ -534,7 +507,8 @@ with qe.Timer(): :label: speed_ex2 ``` -در سری سخنرانی [مقدمه‌ای بر اقتصاد کمی با Python](https://intro.quantecon.org/intro.html) می‌توانید همه چیز درباره زنجیره‌های مارکوف حالت محدود یاد بگیرید. +در سری درس‌های [مقدمه‌ای بر اقتصاد کمی با +Python](https://intro.quantecon.org/intro.html) می‌توانید همه چیز درباره زنجیره‌های مارکوف حالت محدود یاد بگیرید. فعلاً، فقط روی شبیه‌سازی یک مثال بسیار ساده از چنین زنجیره‌ای تمرکز کنیم. @@ -721,7 +695,7 @@ $$ که در آن -1. $\beta$ یک فاکتور تنزیل است، +1. $\beta$ یک ضریب تنزیل است، 2. $n$ تاریخ انقضا است، 2. $K$ قیمت اعمال است و 3. $\{S_t\}$ قیمت دارایی پایه در هر زمان $t$ است. @@ -742,7 +716,7 @@ $$ h_{t+1} = \rho h_t + \nu \eta_{t+1} $$ -در اینجا $\{\xi_t\}$ و $\{\eta_t\}$ IID و نرمال استاندارد هستند. +در اینجا $\{\xi_t\}$ و $\{\eta_t\}$ مستقل و هم‌توزیع و نرمال استاندارد هستند. (این یک مدل **نوسان تصادفی** است، که در آن نوسان $\sigma_t$ در طول زمان تغییر می‌کند.) @@ -750,7 +724,7 @@ $$ (در اینجا `S0` همان $S_0$ و `h0` همان $h_0$ است.) -با تولید $M$ مسیر $s_0, \ldots, s_n$، تخمین Monte Carlo را محاسبه کنید +با تولید $M$ مسیر $s_0, \ldots, s_n$، تخمین مونت‌کارلو را محاسبه کنید $$ \hat P_M