Jak wdrażać współbieżne algorytmy i technologie

Różnica pomiędzy sekwencyjnością, a współbieżnością jest ogromna. Pierwsze podejście przypomina początkującego kucharza, który po kolei wykonuje wskazówki podane w przepisie. Jaki jest efekt? Być może nie umrzesz z głodu, ale czas oczekiwania z całą pewnością będzie zbyt długi.

Dlaczego w ogóle warto się tym zajmować?

Ponieważ w najbliższej przyszłości wzrost wydajności procesorów będzie związany ze zwiększaniem liczby rdzeni, a nie ze wzrostem szybkości działania. W związku z tym jedynym sposobem na pełne wykorzystanie oferowanych możliwości jest równoległe przetwarzanie danych.

Czy trudno zrównoleglić realizowane funkcje?

Czasami jest to proste i wymaga jedynie niewielkiej przeróbki istniejącego kodu. Z taką sytuacją mamy zazwyczaj do czynienia w przypadku, gdy funkcja realizuje wiele niezależnych (nie powiązanych ze sobą logicznie) zadań. Wtedy każde z tych zadań może być zrealizowane na osobnym procesorze.

Jeśli zadanie polega na skompilowaniu kodu źródłowego, to jak najbardziej kompilacja każdego pliku może być zrealizowana niezależnie. Zrównoleglenie takiej funkcjonalności jest więc zadaniem trywialnym.

Rzadko jednak mamy do czynienia z taką niezależnością. Częściej natomiast istnieje konieczność przetworzenia pojedynczej struktury danych (na przykład dużego układu równań lub grafu). Wtedy konieczna jest nowa implementacja algorytmu działającego na tej strukturze.

Projektuj rozwiązania skalowalne!

Przygotowując współbieżną implementację swojej aplikacji nie myśl, że dysponujesz dwoma, czy czterema rdzeniami. Myśl, że jest ich 100, a nawet 1000. Później pójdź jeszcze o krok dalej i załóż, że masz do dyspozycji n rdzeni.

Nie rób tego tak, jak to zrobili producenci gier. Aby jak najszybciej dostosować istniejące oprogramowanie do procesorów wielordzeniowych uruchomili przetwarzanie grafiki i muzyki w osobnych wątkach. Efekt był piorunujący w momencie uruchomienia gry na procesorze dwurdzeniowym. Niestety przejście na procesor czterordzeniowy nie daje już nic.

Jakich narzędzi potrzebuję?

W zasadzie każdy wielozadaniowy system operacyjny dostarcza mechanizmu obsługi wątków. Staraj się jednak unikać rozwiązań charakterystycznych tylko dla jednego systemu operacyjnego (chyba, że jesteś ukierunkowany na tworzenie oprogramowania wyłącznie na ten system). Dobrym rozwiązaniem jest na przykład wykorzystanie standardu POSIX Threads (pthreads), który ma swoją implementację również dla systemu Windows.

Jeżeli jednak chcesz się całkowicie odciąć od bezpośredniego zarządzania pojedynczymi wątkami, to wykorzystaj standard OpenMP. Jest on zdefiniowany dla języków C/C++ i Fortran. Pozwala na bardzo eleganckie przygotowanie programów do pracy współbieżnej. Konieczne jest jednak posiadanie kompilatora, który wspiera ten standard.

Warto również zapoznać się z interfejsem MPI, który umożliwia komunikację pomiędzy wątkami lub procesami działającymi współbieżnie.

Pamiętaj, że współczesne procesory, poza kilkoma rdzeniami oferują również instrukcje typu SIMD (Single Instruction Multiple Data). Są to rozszerzenia, które pozwalają na wykonywanie operacji wektorowych. Spróbuj je wykorzystać, gdyż mogą znacznie podnieść wydajność Twojego systemu.

Zwróć też uwagę na ofertę gotowych bibliotek, które pozwalają na wykonywanie określonych funkcji w sposób równoległy. Jest to dobry wybór w przypadku gdy potrzebujesz implementacji konkretnych algorytmów.