گیاهی ترین گیاهی ترین AnzanDigital فروشگاه

استفاده از CUDA در MATLAB

استفاده از CUDA در MATLAB

بررسی قابلیت‌های معرفی شده توسط Jacket


عرفان نظری فاضل

اشاره:

ماهنامه شبکه – نرم‌افزار Matlab با توجه به دستورها و توابع ساده و محیط داده‌ای برداری‌ای که در بر دارد، یکی از بهترین و کاراترین نرم‌افزارها برای کاربرانی است که دانش عمیقی از برنامه‌نویسی ندارند و نیاز دارند تا وقت و زمان خود را صرف آزمایش طرح‌های جدید و پیش نمونه‌سازی الگوریتم‌های جدید کنند…

 

نرم‌افزار Matlab با توجه به دستورها و توابع ساده و محیط داده‌ای برداری‌ای که در بر دارد، یکی از بهترین و کاراترین نرم‌افزارها برای کاربرانی است که دانش عمیقی از برنامه‌نویسی ندارند و نیاز دارند تا وقت و زمان خود را صرف آزمایش طرح‌های جدید و پیش نمونه‌سازی الگوریتم‌های جدید کنند. پس از معرفی CUDA و فراهم شدن امکان استفاده از قدرت GPU در محاسبات، دو ابزار مناسب برای بهره‌برداری از این توانایی‌ها در محیط Matlab معرفی شدند و در زمینه حل مسائل سنگین ریاضی و فیزیک در شاخه‌های مختلف علوم از جمله مهندسی و پزشکی تحولی شگرف پدید آوردند. این ابزارها GPUmat و Jacket نام دارند که اولی ابزاری رایگان بوده و به سهولت قابل تهیه است. در نقطه مقابل، ابزار Jacket رایگان نیست و در عین حال، امکانات و قابلیت‌های بسیار بهتر و مناسب‌تری دارد. در این مقاله به بررسی قابلیت‌های معرفی شده توسط Jacket می‌پردازیم.

گرافیک در JACKET
همان‌طور که قبلاً اشاره شد، توابع گرافیکی مناسبی برای نمایش داده‌های GPU به صورت مستقیم در Jacket در نظر گرفته شده است که در نوع خود منحصر به فرد بوده و کاربردهای بسیار خوبی دارند. یکی از این توابع، تابع GPlot است که برای کشیدن نمودارهای دو بعدی (همانند Plot در Matlab) به‌کار می‌رود. فهرست ۴ برنامه‌ای نمونه برای استفاده از GPLOT را در بر دارد. شکل ۳ خروجی این برنامه را نشان می‌دهد. توجه کنید که برای استفاده از Gplot باید مسیر m فایل gplot در Jacket را به مسیر اجرایی Matlab اضافه کنید.  یکی دیگر از توابعی که برای نمایش داده‌های GPU در Jacket کاربرد دارد، تابع GSURF است که کاربردی مشابه تابع SURF استاندارد دارد. این تابع یک ماتریس دو بعدی و نرمالایز شده را به‌عنوان ورودی دریافت کرده و به صورت یک نمودار سطحی نمایش می‌دهد. فهرست ۵ برنامه‌ای را برای استفاده از GSURF ارائه می‌کند. خروجی این برنامه در شکل ۴ به نمایش درآمده است. به طور کلی، می‌توان با استفاده از فرمان GFIGURE یک تصویر در فضای GPU تولید کرده و محتوای آن را به دلخواه تعیین کرد. فرمان GFIGURE از لحاظ کاربرد مشابه فرمان FIGURE در محیط Matlab عمل می‌کند. در فهرست ۶ برنامه‌ای برای رسم یک کره چرخان با استفاده از OpenGL در فضای GPU ارائه شده است. خروجی این برنامه را در شکل‌‌۵ مشاهده می‌کنید.

/gfx/gplot.m
A = randn( 1, 100 );     % Initialize a random vector
A = A + abs( min( A ) ); % Rescale the data to [0 1] range
A = A ./ max( A(:) );
gplot( gdouble( A ) );   % Display random image.

فهرست ۴

addpath /gfx
addpath /gfx/mgl
Z = peaks( 30 );          % Generate surface data
Z = Z + abs(min( Z(:) )); % Rescale data in the [0 1] range
Z = Z ./ max( Z(:) );
gsurf( gdouble ( Z ) );   % Display the surface mesh.

فهرست ۵

addpath /gfx
addpath /gfx/mgl
gfigure;
quadratic=gluNewQuadric();
gluQuadricNormals(quadratic, GLU_SMOOTH);
gluQuadricDrawStyle(quadratic,GLU_LINE);
gluQuadricTexture(quadratic, GL_TRUE);
for i=1:10000
  % Do some OGL so that we see something
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
  glTranslatef(0, 0.0, -6.0);
  glRotatef(i/20,0,0.5,0.2);
  glColor3f(1.0, 0.0, 0.0);
  gluSphere(quadratic,2,32,32);
  glXSwapBuffers;
end

فهرست ۶

شکل ۵

ارزیابی
پس از آشنایی با مفاهیم کلی استفاده از قابلیت‌های Jacket و توان پردازشی GPU، نوبت آن می‌رسد تا مزایای استفاده از پردازنده گرافیکی در محاسبات و میزان کارایی آن را در مقابل CPU ارزیابی کنیم. برای این کار، مشابه با آنچه در «مقاله پردازش‌موازی با Matlab» انجام داده‌ایم، در یک برنامه تابعی برای انجام محاسبات سنگین نوشته و دو نمونه از آن را روی CPU و GPU اجرا کرده و زمان‌های اجرا را محاسبه می‌کنیم. با مقایسه این زمان‌ها، می‌توان به دید مناسبی از کارایی GPU نسبت به CPU دست یافت. فهرست ۷  یک تابع  را برای انجام محاسبات سنگین روی CPU یا GPU  در بر دارد. فهرست ۸  فایل استفاده کننده از این تابع را نشان می‌دهد.  خروجی این برنامه مشابه آنچه در مقاله پردازش موازی با Matlab در همین شماره ارائه شده، در فهرست ۹ آورده شده است. همان‌طور که می‌بینید، افزایش سرعت یک پردازنده گرافیکی نسبت به یک پردازنده عادی بسیار خوب و حدود ۲۶ برابر است. با این حال، استفاده از دو پردازنده گرافیکی باعث شده تا سرعت محاسبات کاهش یابد. به این دلیل که این برنامه روی سیستمی اجرا شده است که از دو کارت گرافیک ۹۴۰۰ و ۹۶۰۰ شرکت nVIDIA بهره می‌برده است.

function [ T ] = multibenchNLN( Ain, E )
%multibenchNLN Benchmark based on use of non-linear processing.

%% SET UP VARIABLES
Msz = size(Ain,1);

if strcmp(class(Ain),›gsingle›), % If GPU, predefine GPU variables
    a = gzeros(Msz,1,›single›);
    R = gzeros(Msz,1,›single›);
    k1 = gsingle(pi/4);
    k2 = gsingle(pi/5);
    A = gsingle(Ain);
    geval(a,R,k1,k2,A);
else                             % If CPU, predefine CPU variables
    a = zeros(Msz,1,›single›);
    R = zeros(Msz,1,›single›);
    k1 = single(pi/4);
    k2 = single(pi/5);
    A = single(Ain);
end

%% PERFORM COMPUTATIONS – HERE ONLY THE EXECUTION TIME IS PASSED BACK
gsync;
tstart = tic;
parfor e=1:E
    a = A(:,e);                      % Extract vector from matrix data
    R = k2*a – k1.^2*a.^2 …
        + k2.^2*a.^3 – k1.^3*a.^4 …
        + k2.^4*a.^5 – k1.^5*a.^6 …
        + k2.^7*a.^7 – k1.^8*a.^8 …
        + k2.^9*a.^9 – k1.^10*a.^10 …
        + k2.^11*a.^11 – k1.^12*a.^12 …
        + k2.^13*a.^13 – k1.^14*a.^14 …
        + k2.^15*a.^15 – k1.^16*a.^16 …
        + k2.^17*a.^17 – k1.^18*a.^18 …
        + k2.^19*a.^19 – k1.^20*a.^20;
    geval(a,R);                      % Force computations – does no harm for CPU
end
gsync;
T = toc(tstart);

end

فهرست ۷

%% multibench – benchmarking script to test Jacket with PCT
clear all;
NLNcols = 2^20;
% Number of frames
E = 16;
% Set number of workers
noWorkers = 2;
% Create reference matrix
Aref = rand(NLNcols,E);
%% SINGLE WORKER CPU
if matlabpool(‘size’) > 0
    matlabpool close force;
end
% Input matrix
A = Aref;
% Define CPU variables
[~] = multibenchNLN( A, 4 );
[~] = multibenchNLN( A, 4 );
T_single_CPU = multibenchNLN( A, E );
%% SINGLE WORKER GPU
% Input matrix
A = gsingle(Aref);
% Define GPU variables
[~] = multibenchNLN( A, 4 );
[~] = multibenchNLN( A, 4 );
T_single_GPU = multibenchNLN( A, E );
%% MULTI WORKER CPU
isOpenCorr = matlabpool(‘size’) == noWorkers;
if ~isOpenCorr,
    matlabpool close force
    matlabpool(noWorkers)
end
% Input matrix
A = Aref;
% Define CPU variables
[~] = multibenchNLN( A, 4 );
[~] = multibenchNLN( A, 4 );
T_multi_CPU = multibenchNLN( A, E );
%% MULTI WORKER GPU
% Reference matrix
A = gsingle(Aref);
 % Perform test and clear reference matrices
[~] = multibenchNLN( A, E );
[~] = multibenchNLN( A, E );
T_multi_GPU = multibenchNLN( A, E );
clear Aref;
%% PRINT DATA
fprintf(‘=============================================\n’);
strCPU1 = ‘# Workers: %d  ->   CPU Time [s]:     %۸٫۳f\n’;
fprintf(strCPU1, 1, T_single_CPU);
strGPU1 = ‘# Workers: %d  ->   GPU Time [s]:     %۸٫۳f\n’;
fprintf(strGPU1, 1, T_single_GPU);

strCPU1 = ‘# Workers: %d  ->   CPU Time [s]:     %۸٫۳f\n’;
fprintf(strCPU1, noWorkers, T_multi_CPU);
strGPU1 = ‘# Workers: %d  ->   GPU Time [s]:     %۸٫۳f\n’;
fprintf(strGPU1, noWorkers, T_multi_GPU);
str = ‘Speed-up; 1-CPU / M-CPU [-]:         %۸٫۳f\n’;
fprintf(str, T_single_CPU/T_multi_CPU);
str = ‘Speed-up; 1-GPU / M-GPU [-]:         %۸٫۳f\n’;
fprintf(str, T_single_GPU/T_multi_GPU);
str = ‘Speed-up; 1-GPU / 1-CPU [-]:         %۸٫۳f\n’;
fprintf(str, T_single_CPU/T_single_GPU);
str = ‘Speed-up; M-GPU / M-CPU [-]:         %۸٫۳f\n’;
fprintf(str, T_multi_CPU/T_multi_GPU);
fprintf(‘=============================================\n’);

فهرست ۸

>> multibench
Did not find any pre-existing parallel jobs created by matlabpool.

Starting matlabpool using the ‹local› configuration … connected to 2 labs.
=============================================
# Workers: 1  ->   CPU Time [s]:       ۵۸٫۹۹۲
# Workers: 1  ->   GPU Time [s]:        ۲٫۲۴۵
# Workers: 2  ->   CPU Time [s]:       ۳۰٫۸۳۷
# Workers: 2  ->   GPU Time [s]:        ۲٫۳۷۴
Speed-up; 1-CPU / M-CPU [-]:            ۱٫۹۱۳
Speed-up; 1-GPU / M-GPU [-]:            ۰٫۹۴۶
Speed-up; 1-GPU / 1-CPU [-]:           ۲۶٫۲۷۸
Speed-up; M-GPU / M-CPU [-]:           ۱۲٫۹۸۹
=============================================
>>

فهرست ۹

با این‌که قدرت پردازشی کارت ۹۶۰۰M چیزی حدود دو برابر کارت ۹۴۰۰M است، اما تقسیم مساوی و ۵۰,۵۰ داده‌ها و پردازش بر روی این دو منجر به کاهش سرعت پردازش شده است. برای دستیابی به سرعت بالاتر و مناسب‌تر هنگام استفاده از چند پردازنده‌گرافیکی، روش‌های مختلفی وجود دارد که برای مطالعه بیشتر می‌توانید بخش «منابع و مأخذ» را مشاهده کنید.

جمع­‌بندی
در مقاله حاضر به معرفی یک ابزار مناسب و سودمند در رابطه با استفاده از قدرت پردازشی GPU در محیط کاربر پسند و ساده نرم‌افزار Matlab که یکی از پرکاربرد‌ترین نرم‌افزارها در حوزه محاسبات علمی، فنی و مهندسی است، پرداختیم. این ابزار قابلیت‌های خوبی درباره تبدیل و انتقال داده‌ها روی GPU و نمایش داده‌های GPU به‌صورت مستقیم داشته و با فراهم‌سازی امکاناتی چون کامپایلر اختصاصی برای تولید فایل‌های اجرایی مستقل از Matlab انعطاف بسیار بالایی برای کاربران خود به ارمغان می‌آورد.

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

telegramchanel کانال تلگرام    با عضویت در کانال تلگرام از مطالب آموزشی و مطالب جدید وب سایت مطلع شوید

@matlab24Dotir

جهت عضویت کلیک کنید