Cyfrowe Przetwarzanie Sygnałów na zintegrowanych kartach graficznych

W tych trudnych pandemicznych czasach chyba każdy już zdążył odczuć niedobory mocy obliczeniowej. Drogie procesory, pamięci i karty graficzne, których nie da się kupić… Ta sytuacja zmusza nas do szukania brakujących FLOPSów tam gdzie wcześniej nigdy byśmy nie zajrzeli.  W niniejszym artykule postaramy się pokazać jak duża moc drzemie w układach GPU zintegrowanych z procesorem. W tym celu przetestujemy kilka małych komputerów jednopłytkowych takich jak UDOO BOLT V8 oraz Intel NUC. Uzyskane wyniki porównamy z typowymi maszynami klasy PC wyposażonymi w potężne karty graficzne.

Metoda pomiaru wydajności

Jako, że jesteśmy Kołem Naukowym Radiolokacji i Cyfrowego Przetwarzania Sygnałów to testowany sprzęt sprawdzimy właśnie pod kątem naszej działalności. W sieci można znaleźć bardzo wiele testów opisywanych przez nas platform. Niestety stosuje się tam standardowy zestaw benchmarków, które badają raczej przydatność sprzętu dla graczy lub w zastosowaniach biurowych. Jeżeli wybieramy platformę sprzętową dla potrzeb jakiegoś projektu to takie informacje dają nam jedynie bardzo ogólny ogląd na relacje pomiędzy wydajnością rozwiązań oferowanych przez różnych producentów. Nie jesteśmy w stanie określić dokładnie o ile dany procesor jest szybszy od swojego konkurenta. W naszych zastosowaniach ta relacja może się okazać zupełnie odwrotna. Nie możemy również korzystać tylko z oficjalnej specyfikacji i mocy obliczeniowej deklarowanej przez producenta (z oczywistych względów). Dlatego napisaliśmy własne benchmarki, które pozwalają nam dokładnie określić jak dany algorytm przetwarzania wypada na konkretnym sprzęcie. Prawdziwy mężczyzna sam pisze swoje benchmarki, a kto nie asembluje ten nie je! 

Do testów wykorzystamy więc Kitty FMCW Benchmark – test przetwarzania na potrzeby radaru FMCW takiego jak np. ten. Graficzny interfejs użytkownika prezentuję się tak jak na rysunku 1.

Rysunek 1 Przykładowy wynik Kitty FMCW Benchmark.

Program ten został napisany w C++/OpenCL z wykorzystaniem bibliotek Boost oraz clFFT i Qt5. Pozwala on na sprawdzenie wydajności typowych algorytmów w torze przetwarzania radaru FMCW:

  • Data Transfer – szybkość kopiowania pamięci do i z karty graficznej. 
  • Correlation – obliczanie mapy Range-Doppler oraz filtracja zgodna z algorytmem opisanym tutaj. Konfiguracja pozwala na wybranie layoutu przetwarzanych danych dzięki czemu możliwe jest przetestowanie szybkości dostępu do pamięci globalnej karty w sytuacjach gdy wątki odnoszą się do sąsiadujących lub odległych od siebie komórek pamięci. Poza tym obliczane są FFT i okna.
  • Detection – detekcja CFAR jednym ze standardowych algorytmów opisanych tutaj. Jest to test dwuwymiarowej filtracji dolnoprzepustowej w dziedzinie czasu.
  • Extraction – wyszukanie maksimów lokalnych na mapie Range-Doppler oraz estymacja parametrów echa takich jak prędkość, odległość, SNR, rozmiar.
  • Compression – kompresja mapy Range-Doppler.

Punktacja wyskalowana jest w taki sposób, że wynik większy niż 100 kitty points oznacza przetworzenie danych w czasie rzeczywistym co jest równoznaczne z możliwością zastosowania badanego układu w radarze (jako procesora sygnałowego).

Na potrzeby niniejszego testu przyjęto parametry

  • Częstotliwość nośna f_c= 5,52 GHz;
  • Pasmo B = 48 MHz;
  • PRF = 8 kHz;
  • CPI = 0,25 s;
  • Detektor CA-CFAR – kwadrat o boku 11/11 komórek z oknem bezpieczeństwa 2/2; komórki;
  • Ilość przetwarzanych kanałów – 4.

W czasie trwania benchmarku zmierzony zostanie pobór prądu każdej z badanych platform.

Zestawy testowe

W naszym przypadku karta jest częścią składową procesora Intel® Core i5 7400T. Litera T na końcu nazwy procesora oznacza, że jest to wersja z obniżonym zużyciem energii elektrycznej. W tym wariancie IGPU może rozpędzić się do 1100 MHz, przy zegarze bazowym 350 MHz. Pamięć karty jest współdzielona z procesorem (DDR4 dual channel). Poza tym cechuje ją TDP równe 15 W i wydajność na poziomie 384.0 GFLOPS czyli 384 miliardy operacji zmiennoprzecinkowych pojedynczej precyzji w ciągu sekundy. Oznacza to, że przynajmniej na papierze karta ta jest prawie trzy razy wolniejsza od Radeona HD 4850 wydanego w 2008 roku (1 TFLOPS). Mały pobór prądu sprawia jednak, że jest idealna dla naszych zastosowań gdyż można ją umieścić na maszcie wraz z radarem i zasilać chociażby z akumulatora – dzięki temu nie ma problemu z przesyłaniem danych na duże odległości i nie ma potrzeby mnożenia kabli w często ruchomym maszcie. Karta graficzna Intel® HD 630 oficjalnie wspiera OpenCL w standardzie 3.0 więc wykorzystanie jej do naszych skomplikowanych obliczeń powinno być trywialne.

Procesor umieściliśmy na płycie głównej Asus H110S2 i wyposażyliśmy w dwie pamięci DDR4 SO-DIMM po 8 GB każda oraz dysk NVMe Samsung PM981 . Zestaw znajduje się na zdjęciu z rysunku 2. Format płyty (STX) sprawia, że jest ona idealna do umieszczenia w małym urządzeniu. Dwa złącza RJ45 (1 Gb/s) pozwalają na podłączenie np. dwóch USRP N210 i streamowanie z każdego 20 milionów zespolonych próbek na sekundę (próbki o rozmiarze 16 bit). Płyta jest wyposażona w złącze zasilania 19V podobne do np.  Intel NUC. Oznacza to, że nie musimy umieszczać na maszcie dużego zasilacza dostarczającego wszystkich napięć ze standardu ATX i wystarczy mała przetwornica (65W według zaleceń producenta). Wadą jest brak przydatnych wyjść, które pozwoliłyby na sterowanie sprzętem np. GPIO. Ten problem łatwo obejść stosując odpowiedni moduł USB. Nie ma też możliwości podłączenia karty światłowodowej na potrzeby jeszcze szybszej komunikacji np. z USRP X310. Prawdopodobnie byłoby to możliwe za pośrednictwem specjalnej przejściówki NVMe/PCI-e. Akurat na tej płycie takiego testu nie przeprowadziliśmy gdyż nie oszukujmy się – ten procesor raczej nie potrafi przetworzyć takiej ilości danych jaką może przysłać X310.

Rysunek 2 Zestaw testowy z kartą Intel® HD 630

W takcie testu zestaw pobierał 41.8 W,  a w spoczynku 30.1 W. Zapotrzebowanie na prąd jest wiec zgodne z deklaracjami producenta.

Nasza karta jest zintegrowana a procesorem AMD Ryzen™ Embedded V1605B, a procesor znajduje się na płytce UDOO BOLT V8. Dodatkowo zestaw testowy został uzupełniony o dwie pamięci DDR4 SO-DIMM po 8 GB każda oraz dysk NVMe Samsung PM981. W tym wariancie IGPU może rozpędzić się do 1100 MHz, przy zegarze bazowym 300 MHz. Pamięć karty jest współdzielona z procesorem (DDR4 dual channel). Poza tym cechuje ją TDP na poziomie 65W i wydajność rzędu 1.126 TFLOPS czyli 1126 miliardy operacji zmiennoprzecinkowych pojedynczej precyzji w ciągu sekundy. Oznacza to, że przynajmniej na papierze karta ta jest minimalnie szybsza od Radeona HD 4850 wydanego w 2008 roku (1 TFLOPS). Wysoki współczynnik TDP 65W wydaje się co najmniej wątpliwy biorąc pod uwagę chociażby rozmiar radiatora i to, że producent płytki zaleca stosowanie zasilaczy właśnie o takiej mocy (mają one zaspokoić potrzeby całej platformy z zapasem). Najprawdopodobniej pojawił się błąd w specyfikacji karty na stronie techpowerup – tym chętniej zmierzymy jak to wygląda w praktyce. Karta graficzna Amd Radeon™ Vega 8 Graphics oficjalnie wspiera OpenCL w standardzie 2.1 więc wykorzystanie jej do naszych skomplikowanych obliczeń powinno być trywialne.

Płytka UDOO BOLT V8, której zdjęcie znajduje się na rysunku 3, wydaje się być wprost doskonała do naszych zastosowań. Poza całkiem potężnym procesorem posiada ona rozmaite interfejsy umożliwiające nam np. sterowanie analogowym frontendem mikrofalowym, masztem – po prostu możemy zrobić wszystko. Płytka posiada zestaw wejść i wyjść kompatybilnych z Arduino Leonardo:

  • 12 wejść analogowych,
  • Do 23 wejść/wyjść cyfrowych (7 Pwm),
  • Uart, I2c,  Spi

Poza tym ma wbudowany mikrokontroler ATmega32U4 i 10 pin GPIO. Niestety posiada tylko jedno złącze RJ45  (1Gb/s). Z drugiej strony, można bez problemu podłączyć kartę sieciową PCI-e poprzez zastosowanie przejściówki ze złącza dysku NVMe. Oprócz możliwości podłączenia dysków NVMe i SATA na pytce jest wlutowana pamięć Emmc 5.0 o pojemności 32 GB (wystarczy do uruchomienia prostego systemu operacyjnego). Aktualna cena w oficjalnym sklepie producenta to 514 $. Warto jednak zauważyć, że nie obejmuje ona zasilacza oraz kabelka wyprowadzającego zasilanie dla dysku SATA. Te komponenty musieliśmy zrobić sobie sami. Układ zasilany jest napięciem 19V czyli tak jak np. Intel NUC, ale korzysta z mniej popularnego gniazda męskiego 4.5/3 mm z pinem w środku. Szybko jednak zauważyliśmy, że pin ten nie jest wykorzystywany i pasują również wtyczki, które go nie posiadają. Poza tym istnieje możliwość zasilania przez USB-C. 

W takcie testu zestaw pobierał 39.3 W,  a w spoczynku 12.7 W. Zapotrzebowanie na prąd jest wiec dużo mniejsze niż w znalezionej przez nas specyfikacji układu.

Tym razem karta jest częścią składową procesora Intel® Core™ i7-8559U. W tym wariancie IGPU może rozpędzić się do 1200 MHz, przy zegarze bazowym 300 MHz. Pamięć karty jest współdzielona z procesorem (DDR4 dual channel). Poza tym cechuje ją TDP równe 15 W i wydajność na poziomie 806.4 GFLOPS czyli 806.4 miliarda operacji zmiennoprzecinkowych pojedynczej precyzji w ciągu sekundy. Oznacza to, że przynajmniej na papierze karta ta jest tylko trochę wolniejsza od Radeona HD 4850 wydanego w 2008 roku (1 TFLOPS). Procesor jest wlutowany w płytę główną komputera Intel® NUC NUC8i7BEH (widocznego na zdjęciu z rysunku 4), którego wymiary są zbliżone do UDOO BOLT V8. Karta graficzna Intel® Iris® Plus 655 oficjalnie wspiera OpenCL w standardzie 3.0 więc wykorzystanie jej do naszych skomplikowanych obliczeń powinno być trywialne.

Ten mikrokomputerek nie jest tak dobrze przystosowany do naszych potrzeb jak UDOO BOLT V8. Brakuje mu wielu przydatnych portów i przynajmniej na papierze ma znacznie wolniejsze IGPU. Z drugiej strony udało nam się go zdobyć w zestawie z zasilaczem i kabelkami niezbędnymi do podłączenia dysku SATA. Brak złączy można nadrobić poprzez zastosowanie różnych adapterów USB (są tu 4 porty USB 3.0 + USB-C) Dodatkowo zestaw testowy został wyposażony w dwie pamięci DDR4 SO-DIMM po 8 GB każda oraz dysk NVMe Samsung PM981 –  takie same jak w poprzednich przypadkach. 

Rysunek 4 Wnętrze Intel® NUC NUC8i7BEH

W takcie testu zestaw pobierał 33.8 W,  a w spoczynku 11.4 W. Zapotrzebowanie na prąd jest wiec zbliżone do deklarowanego w specyfikacji urządzenia i mniejsze niż w poprzednich przypadkach.

Testy

Na wszystkich trzech badanych platformach zainstalowaliśmy Windows 10, podstawowe sterowniki i uruchomiliśmy nasz benchmark dla konfiguracji FMCW podanej w części pierwszej. Rozważyliśmy dwa algorytmy filtracji/korelacji. Pierwszy (rysunek 5) z nich jest zoptymalizowany pod względem dostępów do pamięci globalnej tak, żeby kolejne wątki w bloku odwoływały się do następujących po sobie komórek pamięci – w tym celu wykonuje się transpozycję dwuwymiarowej macierzy złożonej z kolejnych SWEEPów w sygnale zdudnień (Range-Doppler przed FFT). Drugi wariant (rysunek 6) takiej optymalizacji nie posiada – rozważamy tu więc przypadek, w którym kolejne wątki muszą odwoływać się do oddalonych od siebie obszarów pamięci. Taki test daje nam rozpoznanie w dwóch kwestiach:

  • jak dobrze musi być napisany kod, żeby działał szybko na danej platformie,
  • jak dany sprzęt poradzi sobie w przypadku algorytmu, który nie pozwala na optymalizowanie dostępów do pamięci globalnej.

Na wykresy z rysunków 5 i 6 nałożyliśmy wyniki uzyskane przy pomocy innych popularnych kart graficznych i procesorów (sprzęt z naszego laboratorium i prywatnych komputerów domowych członków koła – nie jesteśmy przecież profesjonalnymi testerami komputerów do gier więc nie mamy ich w kole zbyt dużo).

Rysunek 5 Wyniki Kitty FMCW Benchmark z transpozycją macierzy (więcej -> lepiej)

Na wykresie z rysunku 5 od razu rzuca się w oczy potwierdzenie tez postawionych na wstępie.

  • Wyniki testów w grach niekoniecznie przekładają się na wydajność w naszych zastosowaniach.   
  • Moc obliczeniowa podana przez producenta nie musi o niczym decydować – papier przyjmie wszystko. Każdy układ ma swoje wąskie gardła, które objawiają się w różnych sytuacjach. Nie można więc z góry założyć, że zawsze uda się wypracować tyle „FLOPSów” ile deklaruje specyfikacja. Skutek jest taki, że w praktyce Intel® NUC NUC8i7BEH  wypada prawie dwa razy lepiej niż UDOO BOLT V8.
Rysunek X

Rysunek 6 Wyniki Kitty FMCW Benchmark bez transpozycji macierzy (więcej -> lepiej)

Na wykresie z rysunku 6 widzimy, że żadna z testowanych IGPU nie radzi sobie z dostępami do pamięci globalnej. Jest to typowe zjawisko, na które odporne są tylko niektóre karty graficzne (np. Radeon VII).  Tym razem żadna z testowanych platform nie pokonała progu 100 kitty points. Oznacza to, że uruchomienie czterokanałowego radaru FMCW, z pasmem rzędu 48 MHz, PRF = 8 kHz i CPI = 0.25 s jest możliwe, ale pod warunkiem, że kod będzie dobrze zoptymalizowany.

Podsumowanie

W ten sposób udało nam się udowodnić, że IGPU może całkiem skutecznie pełnić rolę szybkiego kooprocesora do równoległych obliczeń macierzowych. Są takim jakby dodatkowym Threadripperem, o którym często się zapomina, a który potrafi zdziałać cuda „OpenCL’e”.

Bardzo zawiedliśmy się na UDOO BOLT V8. Nie dość, że wcale nie jest tak szybki jak deklaruje producent to jeszcze napotkaliśmy na poważne problemy ze sterownikami w systemie operacyjnym Ubuntu 18/19/20 (tak, próbowaliśmy 3 różnych wersji, z różnymi kernelami). AMD nie wspiera OpenCL na kartach zintegrowanych w systemach operacyjnych z rodziny Linux. Najwyraźniej tak jak my uważają, że prawdziwy mężczyzna sam pisze swoje sterowniki. Z drugiej strony, czemu mielibyśmy poświęcać na to czas skoro Intel oferuje platformę nie dość, że wydajniejszą to jeszcze z dobrym wsparciem? Warto zauważyć, że NUC, którego testowaliśmy jest już dosyć stary, a na rynku są dostępne nowsze i szybsze wersje tego urządzenia. Niestety tutaj też napotkaliśmy pewne problemy (zarówno z systemem Windows 10 jak i Ubuntu). Nie byliśmy w stanie skompilować niektórych kerneli OpenCL. Okazało się, że istnieje jakieś ograniczenie ich długości, które łatwo przekroczyć na przykład rozwijając pętle for(). Akurat w przypadku naszego kodu jest to standardowy zabieg optymalizacyjny. Na Ubuntu znaleźliśmy obejście problemu poprzez eksperymentowanie z ICD. Niestety w przypadku Windows 10 nie znaleźliśmy rozwiązania. Z tego powodu w jednym miejscu musieliśmy zrezygnować z rozwijania pętli, żeby móc w ogóle uruchomić test (oczywiście ta modyfikacja kodu obejmuje wszystkie wyniki w zestawieniu). Tak czy siak jest to szczegół w porównaniu z kilkudniową walką ze sterownikami AMD.

Ten wpis został opublikowany w kategorii Artykuły, Bez kategorii i oznaczony tagami , , , , , , . Dodaj zakładkę do bezpośredniego odnośnika.