دوشنبه 30 مهر 1397 | Monday 22 nd of October 2018 صفحه اصلی گروه الکترونیکی کامپیوتر
6ـ2 ـ برنامه نویسی CUDA موازی

     پیش از این چگونگی اسان بودن اجرای تابع استاندارد c  را بر روی یک دستگاه دیدیم. با اضافه کردن توصیف کننده __global__  به تابع وبا فراخوانی ان به عنوان یک دستورالعمل پرانتز زاویه دار خاص[]تابع را بر روی GPUاجرا کردیم. اگرچه این اجرا بسیار ساده بود ،  همچنین بسیار ناکارامد نیز بود چراکه عوامل مهندسی سخت افزار NVIDIA  نسبت به عملکرد صدها پردازنده ی محاسباتی موازی در حال بهینه سازی پردازنده های گرافیکی می باشند. با این حال ، تا کنون فقط اقدام به ساخت هسته ای کرده ایم که به صورت ردیفی بر روی GPU  اجرا می شود.در این فصل ، بی پرده می بینیم  که به چه صورت برای راه اندازی یک هسته دستگاه محاسبات خود را به صورت موازی انجام می دهد.

مجموعه بردارها

برای نشان دادن رشته ها یک مثال ساده را طرح ریزی خواهیم کردو اینکه چگونه از رشته ها برای کدگذاری همراه با CUDA Cاستفاده کنیم. تصو کنید دو لیست از اعداد داریم که می خواهیم  عناصر دوبه دو از هر لیست را با یکدیگر جمع کنیم و نتیجه را در لیست سومی ذخیره کنیم. شکل 4_1 این فرایند را نشان می دهد.اگر پیش ضمینه ای در جبر خطی داشته باشید این عملکرد را به عنوان جمع دو بردار تصدیق خواهید کرد.

شکل6ـ1: جمع دوبردار

مجموعه بردارCPU

نخست نگاهی خواهیم انداخت  به راهی که می توانداین عمل جمع را با کدc  قدیمی به انجام برساند

 

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

   

مجموع را داخل یک حلقه whileبه طوریکه دامنه شاخص tidاز0 تاN-1  تغییر می کند محاسبه می کنیم. عناصر مشابه به هم از لیست a[]وb[]را با یکدیگر جمع می کنیم و نتیجه را در لیست c[]قرار می دهیم. به طور معمول در این شیوه کمی ساده تر می شود کدگذاری کرد ، مانند:

در روش کمی پیچیده تر ما می خواست یک راه ممکن را برای جفت کردن کد در سیستم با CPUهای مضاعف یا cpuچند هسته ای پیشنهاد دهد. برای مثال ، با یک پردازنده دو هسته ای ، شمارنده را به مقدار 2 تغییر می دهیم پس یک هسته در حلقه با مقدار اولیه tid  = 0و دیگری باtid   = 1  شروع می  شود. اولین هسته عناصر شاخص زوج را بایکدیگر جمع می کند و دومی عناصر شاخص فرد را با یکدیگر جمع می کند. این مقادیر به شرح  کد ذیل در هر یک از دو هسته CPUاجرا می شوند.

البته انجام این کار بر روی CPUمستلزم در نظر گرفتن کدهای بیشتری است از اینکه در این مثال اورده شده است. شما نیازمند  فراهم کردن مقدار قابل قبولی از زیرساخت برای تولید رشته های کارگر که تابع add()را اجرا کنند هستید و این بهتر است از اینکه فرض کنید هر رشته میتواند به صورت موازی اجرا شود، که این یک زمانبندی فرضی است که متاسفانه همیشه صحیح نمی باشد.

مجموعه بردار GPU

ما می توانیم مشابه همین افزایش را که شباهت زیادی در یک GPU  دارد با نوشتن تابع add()به عنوان تابع دستگاه انجام دهیم. این باید به نظر با کدهایی که در فصل قبلی دیدیم شباهت داشته باشد. اما قبل از اینکه نگاهی به کد دستگاه بیندازیم ،تابع main()  را معرفی می کنیم. اگرچه راه اندازی GPUاز تابعmain()  از نسخه متناظرCPUمتفاوت است. هیچ چیز نباید در اینجا جدید باشد:

  

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

  سه ارایه بر روی دستگاه برای فراخوانی تابع cudaMalloc()  تخصیص می دهیم: دو ارایه dev_a و dev_b،برای نگه داشتن ورودی ها ، ویک ارایه dev_c، برای نگه داشتن نتیجه .

   چون ما کدنویس وظیفه شناس محیطی هستیم ، با دستور cudafree()فضای تخصیص یافته را ازاد می کنیم.

  با استفاده از cudaMemcpy()، داده های ورودی به دستگاه را همراه با پارامترcudaMemcpyHostTo Deviceکپی کرده ونتایج بازگشت داده را به سیستم میزبان توسط cudaMemcpyDeviceToHostکپی می کنیم.

کد دستگاه را در تابع add()  مطابق کد میزبان در تابع main()با استفاده از<<<>>>>اجرا می کنیم

Compatability by:
آخرین به روز رسانی سایت: سه شنبه, 22 اسفند 1391 - 00:26