Pliki źródłowe aplikacji desktopowej służącej do konwersji obrazów o formacie JPG na skalę szarości. Algorytm wykorzystany w programie napisany został w języku assemblera oraz C++ z wykorzystaniem modelu SIMD. Aplikacja utrzymana jest w ciemnej kolorystyce oraz umożliwia wybór liczby wątków i biblioteki Dll.
- Możliwość wyboru biblioteki dll (Asm/Cpp).
- Wybór liczby wątków (1-64).
- Możliwość zapisu przekonwertowanego obrazu.
- Opis wewnątrz aplikacji.
- Zabezpieczenie przed brakiem instrukcji wektorowych w procesorze.
Przy tworzeniu aplikacji zostały wykorzystane następujące technologie:
- Visual Studio 2017 - Środowisko programistyczne.
- .Net 4.7.1 - Framework wykorzystany do tworzenia aplikacji.
- C# - Język programowania, w którym została napisana część obsługi widoków.
- Asm - Język programowania niskiego poziomu wykorzystany do napisania algorytmu konwersji.
- C++ - Język programowania wysokiego poziomu wykorzystany do napisania algorytmu konwersji.
- SIMD - Model architektury umożliwiający wykonywanie wielu operacji na dużej ilości danych jednocześnie.
Dane przekazywane do biblioteki Dll napisanej w języku C++ oraz assemblera odbierane były docelowo jako wskaźnik na tablicę w pamięci o wartości 128 bitów każda. Podział na tablice wykonywany był w części programu napisanej w języku C#, dzięki czemu możliwe było wykorzystanie wielu wątków do obliczeń wartości pixela w skali szarości.
Przekazywana tablica zawierała 16 pixeli każdy po 8 bitów (kanały Red, Green, Blue i Alpha). Tablica wpisywana była w wektor 128-bitowy. Następnie wykonywana została instrukcja shuffle przestawiająca kanały w sposób zaprezentowany na grafice poniżej.
Wizualizacja przetasowania w odpowiednie miejsca wartości rejestru początkowego.
Po ułożeniu pixeli na odpowiedniej tablicy zostały wyodrębnione poszczególne kanały tak aby każdy z nich znajdował się w dolnej częsci osobnego rejestru. Operacja ta została wykonana za pomocą instrukcji przesunięć bitowych (w prawo oraz w lewo).
Przykład otrzymanego rejestru po przesunięciach bitowych eliminujących pozostałe kanały.
Aby obliczyć skalę szarości został zastosowany algorytm polegający na obliczeniu średniej ważonej poszczególnych kanałów pixela.
Gray(R, G, B) = R x 0.29891 + G x 0.58661 + B x 0.11448
Aby pomnożyć wyrazy o długości wyrazu 8-bit przez stałą należy rozszerzyć każdy 8-bitowy wyraz do wyrazu 16-bitowego.
Przykład ułożenia wyrazów po rozszerzeniu do epi16.
Następnie każdy rejestr zawierający odrębny kanał o długości wyrazu 16-bit (short) został pomnożony przez stałą o odpowiedniej wartości. Na koniec wszystkie rejestry zostały zsumowane, a wartości przepisane do wskazanej jako parametr wejściowy tablicy.
Okno wyboru ilości watków, biblioteki źródłowej oraz zapisu obrazu.
Widok wyboru obrazu do konwersji.
Wykres pokazujący różnice w czasie wykonywania operacji algorytmów napisanych w Asm oraz c++.