کتاب حاضر به دانشجویان علوم کامپیوتر و مهندسی نرمافزار که دروس سیستمعامل، محاسبات موازی، برنامهنویسی پیشرفته و پروژه را میگذرانند، پیشنهاد میشود. همچنین برنامهنویسان حرفهای داتنت که میخواهند عملکرد برنامههای خود را بهبود دهند و از تمام هستههای پردازنده استفاده کنند و کدهای ناهمگام مقاوم و مقیاسپذیر بنویسند می توانند از مخاطبین این کتاب باشند.
مدرسان و اساتید دانشگاه که به دنبال منبعی بهروز و کامل با مثالهای عملی و پروژههای آماده هستند، میتوانند از مباحث عملی این کتاب بهره ببرند. همچنین علاقهمندان به مبانی همروندی و موازیسازی که میخواهند درک عمیقی از نحوه کار Task، ThreadPool، Channel و الگوهای رایج داشته باشند، با مطالعه این کتاب به درکی فراتر از مفاهیم سطحی خواهند رسید.
فهرست مطالب
پیشگفتار. 13
فصل اول: مبانی برنامهنویسی موازی. 23
اهداف این فصل. 25
۱-۱ مقدمه: چرا برنامهنویسی موازی؟ 25
1-2 محاسبات چند هستهای (Multicore Computing) 26
1-3 طبقهبندی معماریهای موازی (Taxonomy of Flynn) 27
۱-۳-۱:SISD یک دستور، یک داده (Single Instruction, Single Data) 28
1-3-2 :SIMD یک دستور، چند داده (Single Instruction, Multiple Data) 29
1-3-3 :MISD چند دستور، یک داده (Multiple Instruction, Single Data) 30
1-3-4MIMD : چند دستور، چند داده (Multiple Instruction, Multiple Data) 30
1-4 مفاهیم پایه: فرایند، نخ و Task. 31
1-4-1 فرایند (Process) 31
1-4-2 نخ (Thread) 32
1-4-3) Task واحد انتزاعی کار در داتنت( 32
1-4-4 ایجاد و اجرای یک Task به روش مدرن. 33
1-4-5 تفاوت Task با Thread. 34
1-4-6 تفاوت همروندی (Concurrency) و موازیسازی (Parallelism) 35
1-5 زمانبندی نخها و تعویض متن (Context Switch) 36
۱-۵-۱ نحوة زمانبندی نخها در سیستمعامل. 36
1-5-2 تعویض متن (Context Switch) 37
1-5-3. Oversubscription و Undersubscription 38
1-5-4 مدیریت زمانبندی در داتنت و ThreadPool 39
1-6 همگامسازی (Synchronization) 40
۱-۶-۱ ابزارهای همگامسازی در داتنت. 40
1-6-2 قاعده طلایی در همگامسازی. 41
1-6-3 مثال ساده با عبارت lock. 42
1-7 افزایش سرعت (Speedup) 43
۱-۷-۱ چرا روی ۴ هسته، ۴ برابر سریعتر نمیشود؟ 43
1-7-2 قانون امدال (Amdahl's Law) 44
1-7-3 قانون گوستافسون (Gustafson's Law) – نگاهی واقعبینانهتر. 45
1-8 الگوهای طراحی در برنامهنویسی موازی. 46
1-8-1 الگوهای تجزیه (Decomposition Patterns) 46
1-8-1-1 تجزیه Task (Task Decomposition) 46
1-8-1-2 تجزیه داده (Data Decomposition) 47
1-8-2 الگوهای جریان کار (Algorithm Structure Patterns) 48
1-8-2-1 الگوی تقسیم و غلبه (Divide and Conquer) 48
1-8-2-2 الگوی لولهای (Pipeline) 48
1-8-2-3 الگوی نقشه-کاهش (MapReduce) 48
1-8-3 الگوهای همگامسازی و اشتراک داده 49
1-8-3-1 الگوی داده محلی نخ (Thread‑Local Data) 49
1-8-3-2 الگوی کاهش (Reduction) 49
1-8-3-3 الگوی تولیدکننده‑مصرفکننده (Producer‑Consumer) 49
1-8-4 الگوهای معماری (Supporting Structure Patterns) 49
1-8-4-1 الگوی استخر نخ (Thread Pool) 49
1-8-4-2 الگوی Fork/Join. 49
1-8-4-3 الگوی کارگزار (Master‑Worker) 50
1-9 جمعبندی فصل. 50
تمرینهای فصل اول. 51
فصل دوم: Task و برنامهنویسی ناهمگام (Async/Await) 53
اهداف این فصل. 55
2-1 مقدمه: Taskها، قلب برنامهنویسی موازی مدرن. 55
۲-۲ ایجاد و اجرای Task. 57
2-2-1 متد Parallel.Invoke 57
2-2-2 کلاس Task و متد Task.Run. 58
2-2-3 مقایسه روشهای قدیم و جدید 59
2-3 انتظار برای Taskها 59
2-3-1 انتظار برای یک Task با متد Wait 60
2-3-2 انتظار برای همه Taskها با متد WaitAll 61
2-3-3 انتظار برای اولین Task با متد WaitAny. 61
2-3-4 روش مدرن - استفاده از await 62
2-4 نخها و Taskها: درک رابطه 64
2-4-1 Task یک نخ فیزیکی نیست. 64
2-4-2 هزینههای مرتبط با نخ فیزیکی. 64
2-5Task های دارای مقدار بازگشتی. 65
2-5-1 دریافت نتیجه با استفاده از Task.Run و await 65
2-5-2 استفاده از عبارت لامبدا (Lambda) برای مقدار ثابت. 66
2-5-3 ایجاد Task با سازنده (Constructor) و متد Start (روش قدیمی و کمتر توصیهشده) 67
2-6 مدیریت استثناها در Taskها 68
2-6-1 نحوه ظاهرشدن استثناها در Task. 68
2-6-2 استثناهای چندگانه (Multiple Exceptions) 69
2-6-3 مدیریت انتخابی با AggregateException.Handle 70
2-7 لغو عملیات (Cancellation) 71
2-7-1 مراحل لغو یک Task. 71
2-7-2 مثال لغو یک Task در حال اجرا: 72
2-7-3 نکات مهم در لغو عملیات. 73
2-8 ادامهپذیری (Continuation) با ContinueWith. 74
2-8-1 استفاده ساده از ContinueWith 74
2-8-2 کنترل شرایط اجرا با TaskContinuationOptions 75
2-8-3 روش مدرنتر: استفاده از await به جای ContinueWith 76
2-9 انتظار برای چندین Task به روش مدرن WhenAll و WhenAny. 77
2-9-1 انتظار برای تمامTask ها با WhenAll 77
2-9-2 انتظار برای اولینTask با WhenAny. 78
2-9-3 جمعآوری نتایج با WhenAll (برای Taskهای دارای مقدار بازگشتی) 78
2-10 والد و فرزند (Parent/Child Tasks) 79
2-10-1 ایجاد فرزند متصل به والد با Task.Factory.StartNew. 79
2-10-2 نکات مهم در مورد AttachedToParent 81
2-11 صفهای دزدی کار (Work-Stealing Queue) 81
2-11-1 معماری قدیمی: صف سراسری (Global Queue) 81
2-11-2 معماری مدرن: صفهای محلی (Local Queues) و دزدی کار. 82
2-11-3 نکات پایانی. 83
2-12 مثال عملی: مسابقه الگوریتمهای مرتبسازی. 83
2-12-1 آمادهسازی داده و هماهنگی اولیه 83
2-12-2 تعریف و اجرای Taskهای مرتبسازی. 83
2-12-3 انتظار برای اولین نتیجه و لغو بقیهTask ها 85
2-12-4 نکات مهم و تغییرات نسبت به نسخه قدیم 86
2-13 خلاصه و نکات کلیدی. 86
تمرینهای فصل دوم 87
فصل سوم: موازیسازی داده (Data Parallelism) 89
اهداف فصل. 91
3-1 مقدمه: موازیسازی داده در مقابل موازیسازی وظیفه 91
3-1-1 تعریف موازیسازی داده (Data Parallelism) 92
3-1-2 تفاوت کلیدی با موازیسازی وظیفه (Task Parallelism) 92
۳-۱-۳ اهمیت موازیسازی داده در عصر چند هستهای. 93
3-2 تبدیل حلقههای ترتیبی به موازی. 93
3-2-1 حلقه ترتیبی - Sequential For Loop. 94
3-2-2 حلقه موازی با Parallel.For - تبدیل آسان به موازی. 94
۳-۲-۳ نکات مهم در موازیسازی حلقهها 95
۳-۳ هشدار وابستگیها (Dependencies) در حلقههای موازی. 96
3-3-1 مثال مشکلدار: نوشتن همزمان در یک فایل با StreamWriter 96
3-3-2 راهحل اول: استفاده از قفل (lock) 97
۳-۳-۳ راهحل بهتر- جمعآوری نتایج در مجموعههای نخ-امن (Thread-Safe Collections) 98
3-4 Parallel.ForEach برای مجموعهها 99
3-4-1 مثال اعمال تخفیف روی قیمتها به صورت موازی. 99
3-4-2 نکات مهم درباره Parallel.ForEach 100
3-5 قطع کردن یک حلقه موازیBreak, Stop) ) 101
3-5-1 تفاوت Break و Stop. 101
3-5-2 مثال جستجوی یک مقدار در آرایه با Break. 101
3-5-3 تضمین اجرا در Break در مقابلStop. 102
3-6 مدیریت استثناها در حلقههای موازی. 103
3-6-1 مثال ایجاد استثنا در یکی از تکرارهای حلقه موازی. 103
3-6-2 نکات مهم در مدیریت استثناهای حلقههای موازی. 104
3-7 عملیات کاهش (Reduction) برای جمعآوری نتایج. 105
3-7-1 ساختار پارامترهای localInit, bodyو localFinally در Parallel.ForEach 105
3-7-2 مثال محاسبه مجموع اعداد ۱ تا ۱۰۰۰ به صورت موازی. 105
3-7-3 نکات مهم در عملیات کاهش (Reduction) 106
3-8 الگوی MapReduce برای پردازش حجم بالای داده 107
3-8-1 تعریف و هدف الگوی MapReduce 107
3-8-2 پیادهسازی با Parallel.ForEach و ConcurrentDictionary 107
3-8-3 مراحل Map و Reduce در این مثال. 108
3-8-4 نکات مهم در استفاده از الگوی MapReduce در داتنت. 109
3-9 خلاصه و نکات کلیدی. 109
تمرینهای فصل سوم 110
فصل چهارم: پرسوجوهای یکپارچه موازي (PLINQ) 111
اهداف فصل. 113
4-1 مقدمهای بر LINQ. 113
4-1-1 مزیت اصلی LINQ- یک نحو، چند منبع داده 114
4-1-2 اجرای معوق (Deferred Execution) 114
4-1-3 مثال اجرای معوق. 115
4-2 معرفی PLINQ. 116
4-2-1 تبدیل LINQ ترتیبی به PLINQ موازی. 117
4-2-2 نکات مهم در استفاده از PLINQ. 118
4-2-3 زمان مناسب استفاده از PLINQ. 118
4-3 مقایسهی کارایی LINQ و PLINQ. 119
4-3-1 نمونه کد عملیات سنگین بر روی آرایهای از اعداد 119
4-3-2 خروجی نمونه و تحلیل کارایی. 120
4-3-3 نکات مهم در مورد کارایی PLINQ. 121
۴-۴ متد ForAll برای تکرار موازی. 121
4-4-1 فیلتر کردن رشتهها با PLINQ و چاپ موازی با ForAll 122
4-4-2 مقایسه foreach ترتیبی و ForAll موازی. 123
4-4-3 توصیه برای انتخاب بین foreach و ForAll 123
4-5 تنظیم درجه موازیسازی (WithDegreeOfParallelism) 123
4-5-1 مثال: محدودکردن همزمانی به ۲. 124
4-5-2 موارد استفاده از WithDegreeOfParallelism. 125
4-5-3 نکات مهم در استفاده از WithDegreeOfParallelism. 125
4-6 کنترل ترتیب خروجی (AsOrdered) 125
4-6-1 مثال محاسبه مربع اعداد با حفظ ترتیب. 126
4-6-2 هزینه حفظ ترتیب (کارایی) 127
4-6-3 روشهای جایگزین برای حفظ ترتیب. 127
4-7 ترکیب بخشهای ترتیبی و موازی (AsSequential) 127
4-7-1 مثال فیلتر موازی و مرتبسازی ترتیبی. 128
4-7-2 زمان استفاده از AsSequential 128
4-7-3 نکات مهم درباره AsSequential 129
4-8 رسیدگی به استثناها در PLINQ. 129
4-8-1 مثال تقسیم بر صفر در یک پرسوجوی موازی. 130
4-8-2 نکات مدیریت استثناها در PLINQ. 131
4-8-3 مثال با AggregateException.Handle 131
4-9 لغو عملیات (Cancellation) در PLINQ. 132
4-9-1 تنظیم زمان لغو خودکار با CancelAfter 133
4-9-2 نکات مهم در لغو PLINQ. 134
4-9-3 کاربردهای عملی لغو در PLINQ. 134
4-10 عملیات کاهش (Reduction) در PLINQ. 135
4-10-1 مثال جمع اعداد با Sum موازی. 135
4-10-2 مثال محاسبه فاکتوریل با Aggregate سفارشی. 136
4-10-3 نکات مهم در عملیات کاهش با PLINQ. 137
4-11 الگوی MapReduce باPLINQ. 137
4-11-1 مزیت استفاده از PLINQ برای MapReduce 138
4-11-2 مثال شمارش کلمات در چند فایل متنی با استفاده از PLINQ و MapReduce 138
4-11-3 نکات مهم در پیادهسازی MapReduce با PLINQ. 140
4-12 خلاصه و نکات کلیدی. 140
تمرینهای فصل چهارم 141
پيوستها 143
پیوست ۱: آشنایی با ابزارهای دیباگ موازی در ویژوال استودیو. 145
۱-۱ پنجرهی Parallel Tasks (مشاهدهی همهی Taskهای در حال اجرا) 145
1-2 پنجرهی Parallel Stacks (مشاهدهی پشتهی فراخوانی همهی Taskها) 149
1-3 Concurrency Visualizer (تجسمگر همروندی – نمای زمانی از اجرای برنامه) 151
1-4 نکات عملی برای دیباگ مؤثر کدهای موازی. 155
پیوست ۲: بهترین شیوهها و الگوهای طراحی در موازیسازی داده 157
2-1 چه زمانی اصلاً نباید از موازیسازی استفاده کرد؟ 157
۲-۲ الگوی کاهش (Reduction) – جمعآوری نتایج از چند Task. 159
2-3 همیشه از CancellationToken استفاده کنید (حتی اگر فکر نمیکنید نیاز باشد) 161
2-4 درجهی موازیسازی (Degree of Parallelism) را محدود کنید 163
2-5 الگوی خطایابی گامبهگام برای کدهای موازی. 165
پیوست ۳: سوالات متداول و رفع اشکال. 168
پیوست ۴: مرجع سریع مفاهیم و نکات کلیدی. 174
4-1 مفاهیم پایه (فصل اول) 174
4-2 نکات کلیدی فصل دوم (async/await) 175
4-3 نکات کلیدی موازیسازی داده (فصل سوم) 176
4-4 نکات کلیدی فصل چهارم PLINQ)) 176
4-5 نشانههای خطا و راهحلهای سریع. 177
جمعبندی نهایی پیوستهای جلد اول. 179
سخن پایانی. 181
منابع به تفکیک فصل. 183
| دسته بندی موضوعی | موضوع فرعی |
| فنی و مهندسی |
مهندسی كامپيوتر
مهندسی كامپيوتر |