ГЕТЕРОГЕННІ ПАРАЛЕЛЬНІ ВИЧИСЛЕННЯ НА ПРИКЛАДІ РІШЕННЯ ПОВНОЇ СИСТЕМИ РІВНЯНЬ НАВ’Є-СТОКСУ
Рішення повної системи рівнянь Навье-Стокса методом сіток
Розглядається повна система рівнянь Навье Стокса, рішення якої описують течії в'язкого теплопровідного ідеального газу, що стискається. У системі виконано перехід від змінної щільності та температури до питомого об'єму та тиску. Це дозволяє вирішувати систему рівнянь із приватними похідними у нормальній формі щодо похідних за часом.
У двомірному випадку для безрозмірних змінних ця система має вигляд [1]:

Тут – час, – незалежні просторові змінні. Далі, – питомий обсяг газу, – щільність газу, – тиск, – вектор швидкості газу з його проекціями на декартові осі координат. Постійні коефіцієнти в рівняннях – коефіцієнти в'язкості та теплопровідності, – показник політропи ідеального газу з рівняннями стану, записаними у безрозмірних змінних Для системи (1) розглядається початково-крайове завдання. В області задаються початкові умови виду
(2)
А також крайові умови
(3)
Перші із крайових умов (3) забезпечує прилипання газу на межах області, а другі – забезпечує теплоізоляцію на кордонах. Відповідно до рівняння стану , тоді для забезпечення теплоізоляції достатньо прийняти
При побудові рішень з допомогою різницевих схем по просторовим змінним вводиться рівномірна сітка , . Для дискретизації похідних вибираються такі стандартні вирази (4).
(4)
Рівність нулю похідної температури на межах області апроксимується рівняннями:
(5)
Схема вирішення задачі на GPU з розпаралелюванням
- хост (host) = центральний процесор (CPU);
- пристрій (device) = графічний процесор (GPU);
- потік (stream) – логічна послідовність залежних асинхронних операцій, незалежна від операцій в інших потоках;
- нитка (thread) – елементарний паралельний процес. Усі нитки групуються до ієрархії - grid/block/thread
- грид - безліч процесів, що породжуються запуском ядра
- блок (block) - безліч ниток, в рамках блоку нитки можуть бути синхронізовані, і можуть мати загальну пам'ять, що розділяється (shedder).
Нитки в блоках і блоки в гриді можуть бути представлені у вигляді одно-, дво- або тривимірних грат, ми будемо розглядати одновимірний грид і блок.
- варп (warp) – група ниток, розмір варпа 32 нитки. Усі нитки одного варпа виконуються одночасно синхронно (SIMD) своєму мультипроцессоре.
- ядро (kernel) - функція, що паралельно виконується потоками на GPU;
Програма складається із двох частин:
- host-коду (керуючого коду) написаного на звичайному С/С++, виконується на CPU
- device-коду (апаратного коду) на GPU виконуються спеціальні функції – ядра(kernel) і функції, викликані у них.
Ядро є потоковий (stream) функцією - велика кількість ниток (threads) паралельно виконують тіло ядра (kernel). Ядро викликається з боку CPU, при цьому вказується кількість блоків і кількість ниток у кожному блоці, які його виконуватимуть, а також номер потоку в якому виконуватиметься ядро. Якщо номер потоку не вказано, ядро буде виконано в нульовому потоці. Нульовий потік завжди синхронний.
Потоки бувають синхронні та асинхронні. Синхронний потік означає, що після виклику ядра CPU буде чекати, коли GPU завершить роботу і після продовжить алгоритм. Якщо потік асинхронний, то CPU після виклику ядра продовжить виконувати алгоритм, не чекаючи завершення роботиGPU.
Маємо шар елементів із кроком і відповідно[3,4]. З п'яти елементів даного шару з кроком по часу обчислюються елементи наступного шару. На CPU завдання вирішується запровадженням подвійного циклу. Ідея розв'язання задачі з розпаралелюванням полягає в тому, щоб всі елементи шару були обчислені одночасно, тобто на GPU в рамках першого етапу запускається один потік з кількістю ниток, що паралельно обчислюють елементи наступного шару з кроком . Процес продемонстрований малюнку 1. За кольорами, чорні – обчислені, білі – необхідно обчислити, жовті – обчислюються.

Рис.1 Перший етап – знаходження елементів у наступному шарі на GPU.
2 етап полягає у обчисленні граничних елементів. Граничні елементи обчислюються в два асинхронні потоки (зеленим виділений перший потік, червоним другий потік), перший має ниток і кожна нитка обчислює два елементи, другий потік має ниток і кожна нитка також обчислює два елементи. Для наочності процес показано малюнку 2.

Другий етап – знаходження крайових елементів на GPU.
Кутові елементи обчислюються наприкінці другого етапу ниткою з глобальним індексом "0".
Наведемо лістинг виклику ядер (рис. 3)[5,6], знаходження елементів шару. Як видно з лістингу, перший виклик ядра проходить у нульовому потоці, нульовий потік синхронний, ніби cudaDeviceSynchronize() (функція синхронізації) вставлений до і після кожної CUDA операції. Другий та третій виклик ядра відбувається в асинхронних потоках, тобто вони виконуються одночасно.

Мал. 3 – Лістинг організації виклику ядер.
Ефективність використання CPU та CPU+GPU
У Табл. 1 наведено програмно-апаратне забезпечення, у якому проводилися розрахунки. У Табл. 2одержані результати розрахунків.