Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМК Параллель багдарламалау.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
4.47 Mб
Скачать

Лабораториялық жұмыс №12

Тақырыбы. Матрицалардың тізбекті және параллельді көбейтіндісі

Жұмыс мақсаты. Матрицаларды тізбектей және параллельді көбейтіп үйрену

Тапсырма. №12 лекция материалдарын басшылыққа алып жұмысты орындау.

n=50, 200, 400, 900 мәндері бойынша тізбектей және параллель көбейтуді орындау және уақыттарын салыстыру және әртүрлі worker-лер саны үшін тексеру.

Әдістемелік нұсқау. Өз компьютеріңіздің процессорының сипаттамасын ескеріп, жұмысты орындау.

Лабораториялық жұмыс №13

Тема. Дифференциалды теңдеулерді шешу

Жұмыс мақсаты. Қарапайым дифференциальды теңдеулерге параллель есептеулерді қолдану

Тапсырма. № 13 лекция материалын қолдану. Ұсынылған мысалды 2 worker-ді қолдану арқылы және matlabpool open LOCAL 2 арқылы жүзеге асыру

Әдістемелік нұсқау. Ұсынылған материал көмегімен басқа дифференциалды теңдеулерді шешуде параллельдеу әдістерін қолдану .

Лабораториялық жұмыс №14

Тақырыбы. Gpu (graphics processing unit)қосымша есептеу құралы ретінде

Жұмыс мақсаты. NVIDIA CUDA платформасымен танысу және GPU графикалық редакторын пайдалану.

Тапсырма. №14 лекция материалдарын қайталау.

Тапсырма 1:

Мандельброт жиынтығының 4 жүзеге асырылуын қарастыру:

  1. CPU-мен орындалатын (1 мысал);

  2. gpuArray – ды қолданумен (2мысал)

  3. arrayfunв gpuArray қызметін қолдану арқылы (3мысал)

  4. MATLAB мағлұматтарын қолдана отырып CUDA/C++ ны орындайтын parallel.gpu.CUDAKernel ядроны қолданумен (4мысал).

1 мысал – CPU-да орындау

% қою шрифтпен белгіленген 4 қатар әрбір 4 мысалда қолданылады

maxIterations = 500;

gridSize = 1000;

xlim = [-0.748766713922161, -0.748766707771757];

ylim = [ 0.123640844894862, 0.123640851045266];

% Setup

t = tic();

x = linspace(xlim(1), xlim(2), gridSize );

y = linspace(ylim(1), ylim(2), gridSize );

[xGrid,yGrid] = meshgrid( x, y );

z0 = xGrid + 1i*yGrid;

count = ones( size(z0) );

% Calculate

z = z0;

for n = 0:maxIterations

z = z.*z + z0;

inside = abs( z )<=2;

count = count + inside;

end

count = log( count );

% Show

cpuTime = toc( t );

set(gcf, 'Position', [200 200 600 600] );

imagesc( x, y, count );

axisimage %выводосей

colormap( [jet();flipud( jet() );0 0 0] );

title(sprintf( '%1.2fsecs (without GPU)', cpuTime ) );

Жұмыс нәтижесі (сурет70).

Сурет 70 – Мандельброт жиынтығының бөлігі, CPU-мен орындалған жағдайда

Тапсырма 2:

GPU – ды қолдану

Алдынғы тапсырманы орындау уақыты 7.31 сек құрады (сурет 70)

Алдағы мысалдарда CPU және GPU-да тапсырма орындағанда салыстыру үшін cpuTime=7.31secs – ды аламыз.

2 мысал – gpuArray-дың қолданылуы

% gpuArray қолдану арқылы GPU-ға кірме мәліметтерді қайта құру,

% онда 1 мысалдағы бастапқы алгоритмді өзгеріссіз қалдырамыз

maxIterations = 500;

gridSize = 1000;

xlim = [-0.748766713922161, -0.748766707771757];

ylim = [ 0.123640844894862, 0.123640851045266];

cpuTime=7.31;

% Setup

t = tic();

x = gpuArray(linspace( xlim(1), xlim(2), gridSize ));

y = gpuArray(linspace( ylim(1), ylim(2), gridSize ));

[xGrid,yGrid] = meshgrid( x, y );

z0 = complex(xGrid, yGrid );

count = gpuArray(ones( size(z0) ));

% Calculate

z = z0;

for n = 0:maxIterations

z = z.*z + z0;

inside = abs( z )<=2;

count = count + inside;

end

count = log( count );

% Show

count = gather( count ); % Fetch the data back from the GPU

naiveGPUTime = toc( t );

imagesc( x, y, count )

axis image

title(sprintf( '%1.3fsecs (naive GPU) = %1.1fx faster',naiveGPUTime, cpuTime/naiveGPUTime ) )

GPU-ді қолданғанда тапсырма уақыты 2.3 есе азайды (сурет71).

Сурет 71– GPU-да Мандельброт жиынтығына арналған бағдарламаны орындау нәтижесі

Тапсырма 3:

Келесі, arrayfun көмегімен тапсырманы орындауды қарастырайық.

3 мысал – gpuArray-да arrayfun қызметін пайдалану

maxIterations = 500;

gridSize = 1000;

xlim = [-0.748766713922161, -0.748766707771757];

ylim = [ 0.123640844894862, 0.123640851045266];

cpuTime=7.31;

% Setup

t = tic();

x = gpuArray(linspace( xlim(1), xlim(2), gridSize ));

y = gpuArray(linspace( ylim(1), ylim(2), gridSize ));

[xGrid,yGrid] = meshgrid( x, y );

% Calculate

count = arrayfun( @pctdemo_processMandelbrotElement, ...

xGrid, yGrid, maxIterations );

% Show

count = gather( count ); % Fetch the data back from the GPU

gpuArrayfunTime = toc( t );

imagesc( x, y, count )

axis image

title(sprintf( '%1.3fsecs (GPU arrayfun) = %1.1fx faster', ...

gpuArrayfunTime, cpuTime/gpuArrayfunTime ) );

GPU arrayfun қызметін қолдану арқылы Мандельброт жиынын құру (сурет 72).

Сурет 72- GPU arrayfun қызметін қолдану арқылы Мандельброт жиынтығын құру

Сурет 72-ден байқағанымыздай, CPU-дағы орындалған cpuTime=7.31secs қарағанда жұмыс нәтижесі 24.2 есе ұлғайды.

Тапсырма 4:

4 мысал - CUDA/C++ орындайтын және MATLAB-тан мәліметтерді алатын parallel.gpu.CUDAKernel ядросы қолданылады.

/**

* @file pctdemo_processMandelbrotElement.cu

* CUDA code to calculate the Mandelbrot Set on a GPU.

* Copyright 2011 The MathWorks, Inc.

*/

/** Work out which piece of the global array this thread should operate on */

__device__ size_tcalculateGlobalIndex() {

// Which block are we?

size_tconstglobalBlockIndex = blockIdx.x + blockIdx.y * gridDim.x;

// Which thread are we within the block?

size_tconstlocalThreadIdx = threadIdx.x + blockDim.x * threadIdx.y;

// How big is each block?

size_tconstthreadsPerBlock = blockDim.x*blockDim.y;

// Which thread are we overall?

returnlocalThreadIdx + globalBlockIndex*threadsPerBlock;

}

/** The actual Mandelbrot algorithm for a single location */

__device__ unsigned intdoIterations( double const realPart0,

doubleconst imagPart0,

unsignedintconstmaxIters ) {

// Initialise: z = z0

doublerealPart = realPart0;

doubleimagPart = imagPart0;

unsignedint count = 0;

// Loop until escape

while ( ( count <= maxIters )

&& ((realPart*realPart + imagPart*imagPart) <= 4.0) ) {

++count;

// Update: z = z*z + z0;

doubleconstoldRealPart = realPart;

realPart = realPart*realPart - imagPart*imagPart + realPart0;

imagPart = 2.0*oldRealPart*imagPart + imagPart0;

}

return count;

}

/** Main entry point.

* Works out where the current thread should read/write to global memory

* and calls doIterations to do the actual work.

__global__ void processMandelbrotElement(

double * out,

const double * x,

const double * y,

const unsigned intmaxIters,

const unsigned intnumel ) {

// Work out which thread we are

size_tconstglobalThreadIdx = calculateGlobalIndex();

// If we're off the end, return now

if (globalThreadIdx>= numel) {

return;

}

// Get our X and Y cords

doubleconst realPart0 = x[globalThreadIdx];

doubleconst imagPart0 = y[globalThreadIdx];

// Run the itearations on this location

unsignedintconst count = doIterations( realPart0, imagPart0, maxIters );

out[globalThreadIdx] = log( double( count + 1 ) );

}

Тапсырма 5:

Жоғарыда атап көрсетілген pctdemo_processMandelbrotElement.cu келесі m-файл ісінде қолданылады:

maxIterations = 500;

gridSize = 1000;

xlim = [-0.748766713922161, -0.748766707771757];

ylim = [ 0.123640844894862, 0.123640851045266];

cpuTime=240.89;

% Load the kernel

cudaFilename = 'pctdemo_processMandelbrotElement.cu';

ptxFilename = ['pctdemo_processMandelbrotElement.',parallel.gpu.ptxext];

kernel = parallel.gpu.CUDAKernel( ptxFilename, cudaFilename );

% Setup

t = tic();

x = gpuArray(linspace( xlim(1), xlim(2), gridSize ));

y = gpuArray(linspace( ylim(1), ylim(2), gridSize ));

[xGrid,yGrid] = meshgrid( x, y );

% Make sure we have sufficient blocks to cover all of the

numElements = numel( xGrid );

kernel.ThreadBlockSize = [kernel.MaxThreadsPerBlock,1,1];

kernel.GridSize = [ceil(numElements/kernel.MaxThreadsPerBlock),1];

% Call the kernel

count = gpuArray(zeros( size(xGrid) ));

count = feval( kernel, count, xGrid, yGrid, maxIterations, numElements );

% Show

count = gather( count ); % Fetch the data back from the GPU

gpuCUDAKernelTime = toc( t );

imagesc( x, y, count )

axis image

title(sprintf( '%1.3fsecs (GPU CUDAKernel) = %1.1fx faster', ...

gpuCUDAKernelTime, cpuTime/gpuCUDAKernelTime ) );

Нәтиже (сурет 73)

Сурет 73 - GPUCUDAKernel – CUDA ядросын пайдаланып, Мандельброт жиынтығын жасау

Әдістемелік нұсқау. Теориялық материалды басшылыққа алып, программаларды жүзеге асыру.