CUDA انویدیا یک پلتفرم محاسبات موازی و مدل برنامهنویسی با هدف عمومی است که با بهرهگیری از قدرت پردازش موازی پردازندههای گرافیکی، یادگیری عمیق و سایر برنامههای محاسباتی فشرده را تسریع میکند.
- منشا CUDA
- OpenCL در مقابل CUDA
- افزایش عملکرد CUDA
- دامنه های برنامه CUDA
- CUDA در یادگیری عمیق
- مجموعه ابزار CUDA
- کتابخانههای یادگیری عمیق CUDA
- جبر خطی و کتابخانه های ریاضی CUDA
- کتابخانههای پردازش سیگنال CUDA
- کتابخانههای الگوریتم موازی CUDA
CUDA یک پلت فرم محاسباتی موازی و مدل برنامه نویسی است که توسط NVIDIA برای محاسبات عمومی به تنهایی توسعه یافته است. GPU (واحدهای پردازش گرافیکی). CUDA به توسعه دهندگان این امکان را می دهد تا با استفاده از قدرت پردازنده های گرافیکی برای بخش قابل موازی سازی محاسبات، برنامه های کاربردی محاسباتی را سرعت بخشند.
در حالی که APIهای پیشنهادی دیگری برای پردازندههای گرافیکی، مانند OpenCL وجود دارد، و پردازندههای گرافیکی رقابتی نیز وجود دارند. از شرکتهای دیگر، مانند AMD، ترکیب پردازندههای گرافیکی CUDA و NVIDIA بر چندین حوزه کاربردی، از جمله آموزش عمیق، و پایه ای برای برخی از سریع ترین رایانه های جهان است.
کارتهای گرافیکی احتمالاً به اندازه رایانه شخصی قدیمی هستند – یعنی اگر آداپتور نمایشگر تک رنگ IBM 1981 را یک کارت گرافیک در نظر بگیرید. تا سال ۱۹۸۸، میتوانید یک کارت ۱۶ بیتی ۲ بعدی VGA Wonder از ATI (شرکتی که در نهایت توسط AMD خریداری شد) دریافت کنید. تا سال ۱۹۹۶، می توانید یک شتاب دهنده گرافیک سه بعدی از ۳dfx بخرید تا بتوانید بازی تیراندازی اول شخص Quake را با سرعت کامل اجرا کنید.
همچنین در سال ۱۹۹۶، NVIDIA شروع به تلاش برای رقابت در بازار شتاب دهنده های سه بعدی با محصولات ضعیف کرد، اما هرچه پیش رفت آموخت و در سال ۱۹۹۹ GeForce 256 موفق را معرفی کرد، اولین کارت گرافیکی که GPU نامیده شد. در آن زمان، دلیل اصلی داشتن پردازنده گرافیکی، بازی بود. بعداً مردم از GPU برای ریاضیات، علوم و مهندسی استفاده کردند.
منشا CUDA
در سال ۲۰۰۳، تیمی از محققین به رهبری ایان باک، بروک را معرفی کردند، اولین مدل برنامه نویسی که به طور گسترده پذیرفته شده بود تا C را با ساختارهای موازی داده گسترش دهد. باک بعداً به NVIDIA پیوست و راهاندازی CUDA را در سال ۲۰۰۶ رهبری کرد، اولین راهحل تجاری برای محاسبات با هدف عمومی بر روی پردازندههای گرافیکی.
OpenCL در مقابل CUDA
رقیب CUDA OpenCL در سال ۲۰۰۹ راه اندازی شد، در تلاشی برای ارائه استانداردی برای محاسبات ناهمگن که به پردازنده های Intel/AMD با پردازنده های گرافیکی NVIDIA محدود نمی شد. در حالی که OpenCL به دلیل کلی بودنش جذاب به نظر می رسد، اما در پردازنده های گرافیکی NVIDIA به خوبی CUDA عمل نکرده است و بسیاری از فریم ورک های یادگیری عمیق یا از OpenCL پشتیبانی نمی کنند یا تنها پس از انتشار پشتیبانی CUDA از آن به عنوان یک فکر بعدی پشتیبانی می کنند. p>
تقویت عملکرد CUDA
CUDA در طول سالها دامنه خود را بهبود بخشیده و گسترش داده است، کم و بیش در قفل پردازندههای گرافیکی NVIDIA بهبودیافته. با استفاده از چندین پردازنده گرافیکی سرور P100، می توانید تا ۵۰ برابر بهبود عملکرد را نسبت به CPU ها مشاهده کنید. V100 (در این شکل نشان داده نشده است) برای برخی از بارها ۳ برابر سریعتر است (بنابراین تا ۱۵۰ برابر CPU)، و A100 (همچنین نشان داده نشده است) یکی دیگر ۲ برابر سریعتر است (تا ۳۰۰x CPU). نسل قبلی پردازندههای گرافیکی سرور، K80، ۵ برابر تا ۱۲ برابر بهبود عملکرد را نسبت به CPU ارائه میکرد.
توجه داشته باشید که همه افزایشهای سرعت یکسانی را گزارش نمیکنند، و در نرمافزار آموزش مدلها در پردازندهها، به عنوان مثال با استفاده از کتابخانه هسته ریاضی Intel. علاوه بر این، در خود پردازندهها نیز بهبودهایی صورت گرفته است، که عمدتاً برای ارائه هستههای بیشتر است.
افزایش سرعت پردازندههای گرافیکی به زودی برای محاسبات با عملکرد بالا به دست آمده است. افزایش عملکرد تک رشته ای CPU ها در طول زمان، که قانون مور پیشنهاد می کند هر ۱۸ ماه دو برابر می شود، به ۱۰ درصد در سال کاهش یافته است زیرا سازندگان تراشه با محدودیت های فیزیکی از جمله محدودیت اندازه در وضوح ماسک تراشه و بازده تراشه در طول فرآیند تولید مواجه شده اند. و محدودیت های حرارتی در فرکانس های ساعت در زمان اجرا.
دامنه های برنامه CUDA
پردازندههای گرافیکی CUDA و NVIDIA در بسیاری از زمینههایی که نیاز به عملکرد محاسباتی با ممیز شناور بالا دارند، استفاده شدهاند، همانطور که به صورت تصویری در تصویر بالا خلاصه شده است. فهرست جامع تر شامل:
است
- مالی محاسباتی
- مدلسازی آب و هوا، آب و هوا و اقیانوس
- علوم داده و تجزیه و تحلیل
- یادگیری عمیق و یادگیری ماشین
- دفاع و هوش
- تولید/AEC (معماری، مهندسی، و ساخت و ساز): CAD و CAE (شامل دینامیک سیالات محاسباتی، مکانیک سازه محاسباتی، طراحی و تجسم، و اتوماسیون طراحی الکترونیکی)
- رسانه و سرگرمی (از جمله انیمیشن، مدلسازی، و رندر، تصحیح رنگ و مدیریت دانهبندی، ترکیب، تکمیل و جلوهها، ویرایش، کدگذاری و توزیع دیجیتال، گرافیک روی هوا، روی صحنه، بازبینی و ابزارهای استریو، و گرافیک آب و هوا)
- تصویربرداری پزشکی
- نفت و گاز
- تحقیق: آموزش عالی و ابر محاسبات (شامل شیمی محاسباتی و زیست شناسی، تجزیه و تحلیل عددی، فیزیک و تجسم علمی)
- ایمنی و امنیت
- ابزارها و مدیریت
CUDA در یادگیری عمیق
یادگیری عمیق نیاز بسیار زیادی به سرعت محاسبات دارد. برای مثال، برای آموزش مدلهای Google Translate در در سال ۲۰۱۶، تیمهای Google Brain و Google Translate صدها اجرای TensorFlow یک هفتهای را با استفاده از GPU انجام دادند. آنها برای این منظور ۲۰۰۰ پردازنده گرافیکی درجه سرور از NVIDIA خریداری کرده بودند. بدون پردازندههای گرافیکی، این دورههای آموزشی ماهها طول میکشید تا یک هفته همگرا شوند. برای استقرار تولید آن مدلهای ترجمه TensorFlow، Google از یک تراشه پردازش سفارشی جدید، TPU (واحد پردازش تانسور) استفاده کرد.
علاوه بر TensorFlow، بسیاری از فریم ورکهای یادگیری عمیق دیگر برای پشتیبانی از GPU خود به CUDA متکی هستند، از جمله Caffe2، Chainer، Databricks، H2O.ai، Keras، MATLAB، MXNet، PyTorch، Theano، و Torch. در بیشتر موارد آنها از کتابخانه cuDNN برای محاسبات شبکه عصبی عمیق استفاده می کنند. آن کتابخانه برای آموزش چارچوبهای یادگیری عمیق به قدری مهم است که همه چارچوبهایی که از یک نسخه معین cuDNN استفاده میکنند، اساساً اعداد عملکرد یکسانی برای موارد استفاده معادل دارند. هنگامی که CUDA و cuDNN از نسخه ای به نسخه دیگر بهبود می یابند، تمام چارچوب های یادگیری عمیق که به نسخه جدید به روز می شوند، شاهد افزایش عملکرد هستند. جایی که عملکرد از چارچوبی به فریمورک دیگر متفاوت است، در مقیاس آنها به چندین GPU و چندین گره است.
ابزار CUDA
جعبه ابزار CUDA شامل کتابخانهها، ابزارهای اشکالزدایی و بهینهسازی، کامپایلر، مستندات و کتابخانه زمان اجرا برای استقرار برنامه های کاربردی شما. دارای اجزایی است که از یادگیری عمیق، جبر خطی، پردازش سیگنال و الگوریتم های موازی پشتیبانی می کند.
به طور کلی، کتابخانههای CUDA از تمامی خانوادههای GPUهای NVIDIA پشتیبانی میکنند، اما بهترین عملکرد را در آخرین نسل، مانند V100 دارند، که میتواند ۳ برابر سریعتر از P100 برای بارهای آموزشی یادگیری عمیق باشد، همانطور که در زیر نشان داده شده است. A100 می تواند ۲ برابر سرعت بیشتری اضافه کند. استفاده از یک یا چند کتابخانه سادهترین راه برای بهرهگیری از GPU است، تا زمانی که الگوریتمهای مورد نیاز شما در کتابخانه مناسب پیادهسازی شده باشند.
کتابخانه های یادگیری عمیق CUDA
در حوزه یادگیری عمیق، سه کتابخانه اصلی با شتاب GPU وجود دارد: cuDNN، که من به آنها اشاره کردم. قبلاً به عنوان مولفه GPU برای اکثر چارچوب های یادگیری عمیق منبع باز. TensorRT، که بهینهساز استنتاج یادگیری عمیق و زمان اجرا NVIDIA است. و DeepStream، یک کتابخانه استنتاج ویدیویی. TensorRT به شما کمک میکند مدلهای شبکه عصبی را بهینه کنید، برای دقت پایینتر با دقت بالا کالیبره کنید، و مدلهای آموزشدیده را در مراکز داده، سیستمهای تعبیهشده یا پلتفرمهای محصولات خودرو مستقر کنید.
جبر خطی و کتابخانه های ریاضی CUDA
جبر خطی مبنای محاسبات تانسور و در نتیجه یادگیری عمیق است. BLAS (زیربرنامه های اصلی جبر خطی)، مجموعه ای از الگوریتم های ماتریسی که در فرترن در سال ۱۹۸۹ پیاده سازی شده است، از آن زمان توسط دانشمندان و مهندسان استفاده می شود. cuBLAS نسخه شتابدهی شده توسط GPU از BLAS و با بالاترین کارایی روش برای انجام محاسبات ماتریسی با پردازندههای گرافیکی است. cuBLAS فرض می کند که ماتریس ها متراکم هستند. cuSPARSE ماتریسهای پراکنده را کنترل میکند.
کتابخانه های پردازش سیگنال CUDA
تبدیل فوریه سریع (FFT) یکی از الگوریتمهای اساسی مورد استفاده برای پردازش سیگنال است. یک سیگنال (مانند شکل موج صوتی) را به طیفی از فرکانس ها تبدیل می کند. cuFFT یک FFT با شتاب GPU است.
کدکها، با استفاده از استانداردهایی مانند H.264، ویدئو را برای انتقال و نمایش کدگذاری/فشردهسازی و رمزگشایی/از حالت فشردهسازی میکنند. NVIDIA Video Codec SDK این فرآیند را با پردازندههای گرافیکی سرعت میبخشد.
کتابخانه های الگوریتم موازی CUDA
سه کتابخانه برای الگوریتم های موازی همگی اهداف متفاوتی دارند. NCCL (NVIDIA Collective Communications Library) برای مقیاسبندی برنامهها در چندین GPU و گره است. nvGRAPH برای تجزیه و تحلیل گراف موازی است. و Thrust یک کتابخانه الگوی C++ برای CUDA بر اساس کتابخانه الگوی استاندارد C++ است. Thrust مجموعه ای غنی از داده های اولیه موازی مانند اسکن، مرتب سازی و کاهش را فراهم می کند.
عملکرد CUDA در مقابل CPU
در برخی موارد، میتوانید از توابع CUDA به جای توابع معادل CPU استفاده کنید. برای مثال، روالهای ضرب ماتریس gemm
از BLAS را میتوان به سادگی با پیوند دادن به NVBLAS:
اصول برنامه نویسی CUDA
اگر نمیتوانید روالهای کتابخانه CUDA را برای تسریع برنامههای خود پیدا کنید، باید در برنامه نویسی سطح پایین CUDA. این در حال حاضر بسیار ساده تر از زمانی است که من برای اولین بار آن را در اواخر دهه ۲۰۰۰ امتحان کردم. در میان دلایل دیگر، نحو سادهتر و ابزارهای توسعه بهتر در دسترس است.
تنها ایراد من این است که پشتیبانی macOS برای اجرای CUDA، پس از یک دوره طولانی غیرقابل استفاده از بین رفته است. بیشترین کاری که می توانید در macOS انجام دهید، کنترل اشکال زدایی و نمایه سازی است. جلسات در حال اجرا در لینوکس یا ویندوز.
برای درک برنامه نویسی CUDA، این روال ساده C/C++ را برای اضافه کردن دو آرایه در نظر بگیرید:
void add(int n, float *x, float *y)
{
for (int i = 0; i < n; i++)
y[i] = x[i] + y[i];
}
می توانید با افزودن کلمه کلیدی __global__
به اعلان، آن را به هسته ای تبدیل کنید که بر روی GPU اجرا شود و با استفاده از نحو براکت سه گانه، هسته را فراخوانی کنید:
add<<<1, 1>>>(N, x, y);
همچنین باید تماسهای malloc
/new
و رایگان
/حذف
خود را به cudaMallocManaged تغییر دهید
و cudaFree
به طوری که شما در حال تخصیص فضا در GPU هستید. در نهایت، قبل از استفاده از نتایج در CPU، باید منتظر بمانید تا محاسبه GPU تکمیل شود، که می توانید با cudaDeviceSynchronize
انجام دهید.
براکت سه گانه بالا از یک بلوک رشته و یک رشته استفاده می کند. پردازندههای گرافیکی فعلی NVIDIA میتوانند بسیاری از بلاکها و رشتهها را مدیریت کنند. به عنوان مثال، یک GPU Tesla P100 مبتنی بر معماری GPU Pascal دارای ۵۶ چند پردازنده جریانی است ( اس ام اس)، هر کدام می توانند تا ۲۰۴۸ رشته فعال را پشتیبانی کنند.
کد هسته برای یافتن آفست آن در آرایههای ارسال شده باید بلاک و نمایه رشته خود را بشناسد. هسته موازی شده اغلب از یک grid-stride، مانند موارد زیر:
__global__
void add(int n, float *x, float *y)
{
int index = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
for (int i = index; i < n; i += stride)
y[i] = x[i] + y[i];
}
اگر به نمونههای موجود در CUDA Toolkit نگاه کنید، خواهید دید که چیزهای بیشتری نسبت به اصول اولیه ای که در بالا توضیح دادم وجود دارد. برای مثال، برخی از فراخوانیهای تابع CUDA باید در فراخوانهای checkCudaErrors()
پیچیده شوند. همچنین، در بسیاری از موارد، سریعترین کد از کتابخانههایی مانند cuBLAS همراه با تخصیص حافظه میزبان و دستگاه و کپی کردن ماتریسها به صورت رفت و برگشت استفاده میکند.
به طور خلاصه، میتوانید برنامههای خود را با پردازندههای گرافیکی در سطوح مختلف تسریع کنید. میتوانید کد CUDA بنویسید، میتوانید با کتابخانههای CUDA تماس بگیرید، و میتوانید از برنامههایی استفاده کنید که قبلاً از CUDA پشتیبانی میکنند.
پست های مرتبط
CUDA چیست؟ برنامه نویسی موازی برای پردازنده های گرافیکی
CUDA چیست؟ برنامه نویسی موازی برای پردازنده های گرافیکی
CUDA چیست؟ برنامه نویسی موازی برای پردازنده های گرافیکی