diff --git a/.translate/state/numba.md.yml b/.translate/state/numba.md.yml index 51979e5..54ce38f 100644 --- a/.translate/state/numba.md.yml +++ b/.translate/state/numba.md.yml @@ -1,6 +1,6 @@ -source-sha: f4c6bc9d1cfb2558ca6b62485527dfc0facc2aee -synced-at: "2026-07-15" +source-sha: 7fce1f21833f64eb8ba853fc0d7a36fce53dc3bd +synced-at: "2026-08-12" model: claude-sonnet-5 mode: UPDATE section-count: 5 -tool-version: 0.16.1 +tool-version: 0.25.0 diff --git a/lectures/numba.md b/lectures/numba.md index 9b2175b..d099eaf 100644 --- a/lectures/numba.md +++ b/lectures/numba.md @@ -660,15 +660,15 @@ with qe.Timer(): اکنون سعی کنید موازی‌سازی را اضافه کنید و ببینید آیا افزایش سرعت بیشتری به دست می‌آورید. -نباید انتظار افزایش بزرگی در اینجا داشته باشید زیرا، در حالی که وظایف مستقل زیادی وجود دارد (کشیدن نقطه و آزمایش اگر در دایره است)، هر کدام زمان اجرای کمی دارد. +در اینجا وظایف مستقل زیادی وجود دارد (کشیدن یک نقطه و آزمایش اینکه آیا در دایره قرار می‌گیرد)، اما هر کدام زمان اجرای بسیار کمی دارد. -به طور کلی، موازی‌سازی زمانی کمتر موثر است که وظایف فردی که باید موازی شوند نسبت به کل زمان اجرا بسیار کوچک باشند. +به طور کلی، موازی‌سازی زمانی کمتر موثر است که وظایف فردی نسبت به سربارهای توزیع آن‌ها در چندین CPU بسیار کوچک باشند. -این به دلیل سربارهای مرتبط با توزیع همه این وظایف کوچک در چندین CPU است. +راه‌حل این مشکل این است که به هر نخ کار کافی بدهیم تا آن سربارها ارزش پرداخت داشته باشند. -با این وجود، با سخت‌افزار مناسب، امکان به دست آوردن افزایش سرعت غیر بدیهی در این تمرین وجود دارد. +پس، برای اندازه شبیه‌سازی Monte Carlo، از چیزی قابل توجه استفاده کنید، مانند `n = 100_000_000`. -برای اندازه شبیه‌سازی Monte Carlo، از چیزی قابل توجه استفاده کنید، مانند `n = 100_000_000`. +در این مقیاس، و با سخت‌افزار مناسب، باید افزایش قابل توجهی نسبت به نسخه سریال ببینید. ``` ```{solution-start} numba_ex3 @@ -692,23 +692,49 @@ def calculate_pi_parallel(u_draws, v_draws): return area_estimate * 4 # تقسیم بر radius**2 ``` -حالا بیایید ببینیم چقدر سریع اجرا می‌شود: +موازی‌سازی زمانی سودمند است که هر نخ کار کافی برای غلبه بر هزینه‌های سربار داشته باشد، در حالی که مسئله را به بخش‌هایی تقسیم می‌کند تا کار به طور همزمان اتفاق بیفتد. + +بیایید مجموعه جدید و بسیار بزرگ‌تری از نقاط را بکشیم به جای استفاده مجدد از آرایه‌های بالا. + +```{note} +دو آرایه زیر حدود 1.6 گیگابایت حافظه اشغال می‌کنند — اگر دستگاه شما حافظه رم کافی ندارد، `n` را کاهش دهید. +``` + +```{code-cell} ipython3 +n = 100_000_000 +rng = np.random.default_rng() +u_big = rng.uniform(size=n) +v_big = rng.uniform(size=n) +``` + +حالا بیایید ببینیم چقدر سریع اجرا می‌شود (فراخوانی دوم زمان اجرا را بدون زمان کامپایل اندازه‌گیری می‌کند): ```{code-cell} ipython3 with qe.Timer(): - calculate_pi_parallel(u_draws, v_draws) + calculate_pi_parallel(u_big, v_big) ``` ```{code-cell} ipython3 with qe.Timer(): - calculate_pi_parallel(u_draws, v_draws) + calculate_pi_parallel(u_big, v_big) +``` + +برای مقایسه، در اینجا نسخه سریال jit شده از {ref}`speed_ex1` روی همان نقاط است: + +```{code-cell} ipython3 +with qe.Timer(): + calculate_pi(u_big, v_big) ``` -با روشن و خاموش کردن موازی‌سازی (انتخاب `True` یا `False` در annotation `@jit`)، می‌توانیم افزایش سرعتی که چندنخی علاوه بر کامپایل JIT فراهم می‌کند را آزمایش کنیم. +با مقایسه دو زمان‌بندی آخر، چندنخی افزایش سرعت قابل توجهی علاوه بر کامپایل JIT فراهم می‌کند. + +(اگر به صورت محلی اجرا می‌کنید، نتایج متفاوتی خواهید گرفت که عمدتاً به تعداد CPUها در دستگاه شما بستگی دارد — و در اندازه‌های نمونه کوچک، نسخه موازی می‌تواند حتی کندتر باشد، زیرا سودها نمی‌توانند هزینه توزیع کار میان نخ‌ها را پوشش دهند.) -در ایستگاه کاری ما، می‌بینیم که موازی‌سازی در اینجا افزایش سرعت متوسط اما ارزشمندی فراهم می‌کند. +این دو آرایه بزرگ هستند و کار ما با آن‌ها تمام شده است، پس حافظه را قبل از ادامه دادن آزاد می‌کنیم. -(اگر به صورت محلی اجرا می‌کنید، نتایج متفاوتی خواهید گرفت که عمدتاً به تعداد CPUها در دستگاه شما بستگی دارد.) +```{code-cell} ipython3 +del u_big, v_big +``` توجه کنید که ما همه نقاط تصادفی را *قبل از* حلقه کشیدیم و آن‌ها را به صورت آرایه عبور دادیم، بنابراین حلقه موازی فقط از حافظه *می‌خواند*.