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

Реализация на cuda базовых операций над массивами.

Редукция, сканирование, сортировка.

Преимущества от использования cuda сильно зависят от используемых алгоритмов.

Редукция.

Пусть задан массив a0,a1,…,an-1. требуется выполнить некоторую бинарную ассоциативную операцию над ними. Редукцией данного массива относительно заданной операции будет следующая величина: A=(((a0+a1)+a2)+…+an-1).

Для редукции применим стандартный прием, при котором исходный массив делится на части, которым ставится в соответствие один блок сетки. Он будет считать сумму элементов данной части массива. Таким образом задача разбивается на набор независимых подзадач, а именно нахождение отдельных сумм массива. Далее разобьем соответствующий блок элементов массива на пары. Каждая пара параллельно складывается. В результате получается вдвое больше элементов, подлежащих суммированию. Для данной задачи главным фактором, ограничивающим быстродействие, является доступ к памяти. Поэтому удобно, чтобы каждый блок сразу скопировал элементы в разделяемую память и суммировал их уже в разделяемой памяти.

#define block_size 256

__global__ void reduce (int *inData, int *outData)

{ __shared__ int data[block_size];

int tid = threadIdx.x;

int i = blockIdx.x*blockDim.x+threadIdx.x;

data[tid] = indata[i];

__syncthreads ( );

for (int s=1; s<blockDim.x; s/=2)

{ if (tid%(2*s)==0)

data[tid]+=data[tid+s];

__syncthreads ( );

}

if (tid==0) outData[blockIdx.x]=data[0];

}

(Ui-1,j – 2*Ui,j + Ui+1,j)/h^2+( Ui,j-1 – 2*Ui,j + Ui,j+1)/h^2 = 0

Us+1i,j = ¼*( Us+1i-1,j + Usi+1,j + Us+1i,j-1+ Usi,j+1) – метод Либнана.

Есть еще метод верхней релаксации. Ui,j = Θ/4*( Ui-1,j + Ui+1,j + Ui,j-1+ Ui,j+1)+Ui,j*(1-Θ), Θ= 1,87.

Это первый этап расчета поля потенциалов.

Второй этап. I = -γ*gradU. Ix = -γ*dU/dx, Iy = -γ*dU/dy.

Ixi,j = -γi,j*(Ui+1,j-Ui-1,j)/(2*h), Iyi,j = -γi,j*(Ui,j+1-Ui,j-1)/(2*h).

Третий этап.

dT/dt = A*(d2T/dx2+d2T/dy2)+B*r*(Ix^2+Iy^2)

(Tk+1i,j – Tki,j )/t = A*((Tki-1,j – 2*Tki,j+Tki+1,j)/h^2+(Tki,j-1 – 2*Tki,j + Tki,j+1)/h^2)+B*ri,j *(Ixi,j^2+Iyi,j^2).

dNB/dt = DB*(d2NB/dx2+d2NB/dy2) – M*TBy*NB.

(Nk+1B - NkB)/r = DB*((NkBi-1,j – 2*NkBi,j+NkBi+1,j)/h^2+(NkBij-1 – 2*NkBi,j + NkBi,j+1)/h^2) – M*(Tki,j)^B*NkB.

Граничные условия.

Г1: dU/dy = 0, (Ui,ny – Ui,ny-1)/h = 0, Ui,ny = Ui,ny-1.

Г2: dU/dx = 0, (Unx,j – Unx-1,j)/h = 0, Unx,j = Unx-1,j.

Г3: Ui,1 = 0, i = nx2,…, nx.

Г4: Ui,1 = Ui,2, i=nx1+1,…,nx2-1.

Г5: Ui,1 = 40, i=1,…,nx1.

Г6: U1,j = U2,j.

Для температуры.

α*(T* - T) = λ*dT/dx, α – коэффициент теплопередачи, λ – коэффициент теплопроводности.

α*(T* - T1,j) = λ*(T1,j – T2,j)/h = Q

T1,j*(1- α*h/ λ) = T2,j + α*h/ λ*T*

T1,j = (T2,j + α*h/ λ*T*)/(1+ α*h/ λ)

Tnx,j = (Tnx-1,j + α*h/ λ*T*)/(1+ α*h/ λ)

Ti,1 = (Ti,2 + α*h/ λ*T*)/(1+ α*h/ λ)

Ti,ny = (Ti,ny-1 + α*h/ λ*T*)/(1+ α*h/ λ)

Для влажности.

α*(N* - N1,j) = λ*(N1,j – N2,j)/h

b = 878, T* = 283K, M = 75*10^(-6), B = 1,9, λ = 0,2, c = 1000, α = 4, DB = 10^(-9), ρ = 2450.

ПО, а именно качество, является сдерживающим фактором для развития параллельных систем. Основной характеристикой, определяющей стиль программирования, является наличие общей или распределенной памяти. Отличительной чертой этих систем является единая подсистема ввода-вывода, единая ОС, единая ОП. Обычно работа происходит с использованием Unix подобной ОС. Она функционирует в виде множества процессов. Каждая пользовательская программа также запускается как отдельный процесс. Механизм порождения процесса является главным принципом распараллеливания. Также его называют механизмом порождения нитей. Нить в данном контексте – это легковесный процесс, для которого не порождается отдельного адресного пространства.

В языке Си возможно прямое использование механизма порождения нитей для распараллеливания программы посредством вызова системных функций: Все производители SMP-систем включают в свое ПО распараллеливающие компиляторы. Наиболее часто поставщики SMP-систем предусматривают в компиляторах директивы для распараллеливания цикла. Довольно часто эти наборы директив не совместимы между собой, поэтому приходится распараллеливать программу отдельно для каждой платформы.

Open MP – система, являющаяся расширением и обобщением этого набора директив. Интерфейс этой системы задуман как стандарт для программирования в модели общей памяти. Он реализует идею инкрементального распараллеливания, позаимствованную из языка HPF. Согласно этой системе разработчик не создает новую параллельную программу, а добавляет в текст последовательной программы Open MP директивы. Вся программа делится на последовательные и параллельные области. Все последовательные области выполняет главная нить, порождаемая при запуске. При входе в параллельную часть главная нить порождает дополнительные нити. Наличие общей памяти не препятствует использованию технологий, разработанных для систем с распределенной памятью. Многие производители SMP предоставляют такие технологии, как MPI. В случае таких систем при использовании данной технологии в качестве коммуникационной среды выступает разделяемая память.