Kilka dni temu opublikowano wyniki eksperymentu organizacja w oparciu o uruchomienie Jądro Linuksa w wirtualnej przestrzeni 3D gry online dla wielu graczy.
Ten eksperyment Zostało to zrobione na VRChat, który umożliwia wczytywanie modeli 3D z własnymi shaderami. W celu realizacji wymyślonego pomysłu stworzono emulator oparty na architekturze RISC-V, który jest wykonywany po stronie GPU w postaci pixel shadera.
O projekcie
Emulator oparty na implementacji w języku C, którego tworzenie z kolei wykorzystywało osiągnięcia minimalistycznego emulatora riscv-rust, który z kolei jest rozwijany w języku Rust. Przygotowany kod C jest tłumaczony na pixel shader w języku HLSL, odpowiedni do załadowania do VRChat.
Emulator zapewnia pełne wsparcie dla architektury zestawu instrukcji rv32imasu, jednostka sterująca pamięcią SV32 i minimalny zestaw urządzeń peryferyjnych (UART i timer). Przygotowane możliwości wystarczą do załadowania jądra Linux 5.13.5 oraz podstawowego środowiska wiersza poleceń BusyBox, z którym można wchodzić w interakcję bezpośrednio z wirtualnego świata VRChat.
Około marca 2021 zdecydowałem się napisać emulator zdolny do uruchomienia pełnego jądra Linuksa w VRChat. Ze względu na nieodłączne ograniczenia tej platformy wybrane narzędzie musiało być shaderem. Po kilku miesiącach pracy z dumą przedstawiam pierwszy na świecie emulator procesora/SoC RISC-V (o którym wiem) w pixel shaderze HLSL, który może pracować z częstotliwością do 250 kHz (na 2080 Ti) i uruchom Linux 5.13.5 z obsługą MMU.
Emulator jest zaimplementowany w shaderze w postaci własnej dynamicznej tekstury (Unity Custom Render Texture), uzupełnionej o skrypty Udon dostarczone dla VRChat, które służą do sterowania emulatorem w czasie wykonywania.
Zawartość pamięci głównej i stan procesora emulowanego systemu są zapisywane jako tekstura o rozmiarze 2048×2048 pikseli, dzięki czemu emulowany procesor pracuje z częstotliwością 250 kHz. Oprócz Linuksa na emulatorze można również uruchomić Micropython.
Myślałem, że do uruchomienia Linuksa będziemy potrzebować co najmniej 32 MB pamięci głównej (RAM), ale bądźmy bezpieczni i zróbmy 64 - różnica w wydajności nie będzie duża i powinno być wystarczająco dużo pamięci VRAM.
Początkowo głównym problemem dotyczącym wydajności była szybkość zegara. To znaczy, ile cykli procesora można wykonać w jednej ramce.
Aby zorganizować przechowywanie danych wytrwały ze wsparciem czytania i pisania, zastosowano sztuczkę związaną z użyciem obiektu Camera połączonego z prostokątnym obszarem generowane przez shader i kierując wynik renderowanej tekstury do wejścia shadera. W związku z tym, Dowolny piksel napisany podczas wykonywania programu do cieniowania pikseli można odczytać, przetwarzając następną klatkę.
Po zastosowaniu programów do cieniowania pikseli osobna instancja modułu cieniującego jest uruchamiana równolegle dla każdego piksela w teksturze.
Cecha ta znacznie komplikuje implementację i wymaga osobnej koordynacji stanu całego emulowanego systemu oraz porównania położenia przetwarzanego piksela ze stanem zawartości procesora lub pamięci RAM emulowanego w nim systemu (każdy piksel może zakodować 128 bitów Informacja).
W tym przypadku kod modułu cieniującego wymaga włączenia dużej liczby sprawdzeń, aby uprościć implementację, której użyto preprocesor perl perlpp.
Dla tych, którzy są zainteresowany specyfikacją wspomina się, że:
- kod jest na GitHub
- 64 MiB pamięci RAM minus stan procesora jest przechowywany w teksturze formatu 2048 × 2048 pikseli (128 bpp) w formacie liczby całkowitej
- Niestandardowa tekstura renderowania Unity z wymianą buforów umożliwia kodowanie / dekodowanie stanu między klatkami
- do emulacji używany jest pixel shader, ponieważ shadery obliczeniowe i UAV nie są obsługiwane przez VRChat
W końcu jeśli chcesz dowiedzieć się więcej na ten tematmożesz sprawdzić szczegóły W poniższym linku.