تاريخ : سه شنبه سیزدهم تیر ۱۳۹۱

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

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

/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.

فهرست 4

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.

فهرست 5

 

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

فهرست 6

شکل 5

 

ارزیابی
پس از آشنایی با مفاهیم کلی استفاده از قابلیت‌های Jacket و توان پردازشی GPU، نوبت آن مي‌رسد تا مزایای استفاده از پردازنده گرافیکی در محاسبات و میزان کارایی آن را در مقابل CPU ارزیابی كنيم. برای این کار، مشابه با آنچه در «مقاله پردازش‌موازی با Matlab» انجام داده‌ایم، در یک برنامه تابعی برای انجام محاسبات سنگین نوشته و دو نمونه از آن را روی CPU و GPU اجرا کرده و زمان‌های اجرا را محاسبه مي‌كنيم. با مقایسه این زمان‌ها، مي‌توان به دید مناسبی از کارایی GPU نسبت به CPU دست یافت. فهرست 7  یک تابع  را برای انجام محاسبات سنگین روی CPU یا GPU  در بر دارد. فهرست 8  فایل استفاده کننده از این تابع را نشان مي‌دهد.  خروجی این برنامه مشابه آنچه در مقاله پردازش موازی با Matlab در همین شماره ارائه شده، در فهرست 9 آورده شده است. همان‌طور که مي‌بینید، افزایش سرعت یک پردازنده گرافیکی نسبت به یک پردازنده عادی بسیار خوب و حدود 26 برابر است. با این حال، استفاده از دو پردازنده گرافیکی باعث شده تا سرعت محاسبات کاهش یابد. به اين دلیل که این برنامه روی سیستمی اجرا شده است که از دو کارت گرافیک 9400 و 9600 شرکت 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

فهرست 7

%% 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]:     %8.3f\n’;
fprintf(strCPU1, 1, T_single_CPU);
strGPU1 = ‘# Workers: %d  ->   GPU Time [s]:     %8.3f\n’;
fprintf(strGPU1, 1, T_single_GPU);
 
strCPU1 = ‘# Workers: %d  ->   CPU Time [s]:     %8.3f\n’;
fprintf(strCPU1, noWorkers, T_multi_CPU);
strGPU1 = ‘# Workers: %d  ->   GPU Time [s]:     %8.3f\n’;
fprintf(strGPU1, noWorkers, T_multi_GPU);
str = ‘Speed-up; 1-CPU / M-CPU [-]:         %8.3f\n’;
fprintf(str, T_single_CPU/T_multi_CPU);
str = ‘Speed-up; 1-GPU / M-GPU [-]:         %8.3f\n’;
fprintf(str, T_single_GPU/T_multi_GPU);
str = ‘Speed-up; 1-GPU / 1-CPU [-]:         %8.3f\n’;
fprintf(str, T_single_CPU/T_single_GPU);
str = ‘Speed-up; M-GPU / M-CPU [-]:         %8.3f\n’;
fprintf(str, T_multi_CPU/T_multi_GPU);
fprintf(‘=============================================\n’);

فهرست 8

 

>> 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]:       58.992
# Workers: 1  ->   GPU Time [s]:        2.245
# Workers: 2  ->   CPU Time [s]:       30.837
# Workers: 2  ->   GPU Time [s]:        2.374
Speed-up; 1-CPU / M-CPU [-]:            1.913
Speed-up; 1-GPU / M-GPU [-]:            0.946
Speed-up; 1-GPU / 1-CPU [-]:           26.278
Speed-up; M-GPU / M-CPU [-]:           12.989
=============================================
>>

فهرست 9

با این‌که قدرت پردازشی کارت 9600M چیزی حدود دو برابر کارت 9400M است، اما تقسیم مساوی و 50,50 داده‌ها و پردازش بر روی این دو منجر به کاهش سرعت پردازش شده است. برای دستیابی به سرعت بالاتر و مناسب‌تر هنگام استفاده از چند پردازنده‌گرافیکی، روش‌های مختلفی وجود دارد که برای مطالعه بیشتر مي‌توانيد بخش «منابع و مأخذ» را مشاهده كنيد.

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


برچسب‌ها: حل یک معادله غیر تحلیلی با متلب, پیاده سازی الگوریتم SPID4, 7 با matlab, 7 با مت لب

ارسال توسط بهرامی

اسلایدر

دانلود فیلم