Skocz do: nawigacji, wyszukiwania

MICLAB:Model odciazeniowy


Środowisko i modele programowania

dr inż. Łukasz Szustak, Politechnika Częstochowska, IITiS
mgr inż. Kamil Halbiniak, Politechnika Częstochowska, IITiS



Odciążeniowy model programowania


Odciążeniowy model programowania (offload model) umożliwia tworzenie programów, w których jedynie wybrane segmenty kodu wykonywane są przez koprocesor. Implementacja tego typu aplikacji wymaga użycia dedykowanej do tego celu dyrektywy kompilatora. Pragma #pragma offload target(mic) określa instrukcje lub blok instrukcji, który ma zostać zrealizowany w ramach akceleratora. Dyrektywa offload pozwala również określić, który z dostępnych w systemie koprocesorów zostanie wykorzystany do wykonania obliczeń. Wówczas konstrukcja klauzuli target przyjmuje następującą postać: target(mic:target_id), gdzie target_id określa numer akceleratora. Przykład kodu źródłowego napisanego w oparciu o odciążeniowy model programowania zaprezentowano na Listingu 1.


#include <stdio.h> 
#include <unistd.h>

int main()
{
   printf("Frgment kodu wykonywany przez CPU: \n"
                 " Liczba dostepnych logicznych rdzeni: %d\n",
                    sysconf(_SC_NPROCESSORS_ONLN ));

   #pragma offload target(mic)
   {
      printf("Frgment kodu wykonywany przez MIC: \n"
                    " Liczba dostepnych logicznych rdzeni: %d\n",
                       sysconf(_SC_NPROCESSORS_ONLN ));
   }

   return 0;
}
Listing 1. Kod programu w odciążeniowym modelu programowania


Kompilacja programu odbywa się w tradycyjny sposób - jako zwykłą aplikację hosta. Program uruchamiany jest na procesorze hosta, a segmenty kodu, które mają zostać wykonane przez koprocesor są do niego automatycznie kopiowane w trakcie działania aplikacji, a następnie tam uruchamiane. Przykład kompilacji oraz uruchomienia kodu przedstawionego na Listingu 1 zilustrowano na Rysunku 1.


Offload.png
Rysunek 1. Rezultat uruchomienia aplikacji w trybie odciążeniowym


Dyrektywa offload pozwala również określić kierunek przepływu danych. Do tego celu wykorzystuje się klauzule in, out oraz inout, określające zmienne programu przesyłane pomiędzy koprocesorem oraz hostem. Przykład wykorzystania omawianego mechanizmu zaprezentowano na Listingu 2.


#include <stdio.h>
#include <unistd.h>

int main()
{
   int var = 1;
   printf("CPU: Przed blokiem offload var = %d\n", var);
   #pragma offload target(mic) inout(var)
   {
      printf("MIC: Wartość zmiennej var = %d\n", var);
      var = 2;
   }
 
   printf("CPU: Po bloku offload var = %d\n", var);
   return 0;
}
Listing 2. Mechanizm przepływu danych w modelu odciążeniowym


W przedstawionym powyżej kodzie programu kierunek przepływu danych określony został przy pomocy klauzuli inout, pozwalającej na przesyłanie danych w dwóch kierunkach. Do koprocesora przesyłana zostaje zmienna var, która została początkowo zainicjalizowana oraz wyświetlona przez hosta. W koprocesorze przypisywana jest jej nowa wartość, która wyświetlona zostaje po wykonaniu operacji w bloku offload. Rezultat kompilacji oraz uruchomienia kodu źródłowego przedstawionego na Listingu 2 zaprezentowano poniżej.


Offload data.png
Rysunek 2. Mechanizm przepływu danych w trybie odciążeniowym



< Natywny model programowania

Symetryczny model programowania >