Gdzie się podział Windows dla procesorów ARM i czy jeszcze wróci?
Ten temat był prezentowany na HotZlocie 2019. Dziękujemy, że byliście z nami!
Rok 2018 obfitował w wiadomości dotyczące nadchodzących laptopów i tabletów zaopatrzonych w procesory ARM, ale zdolnych do uruchamiania pełnej wersji Windows, w dodatku zgodnej z dotychczasowymi aplikacjami Win32. Miało to być odkupienie za porażkę platformy Windows RT: wersji Okien działającej na procesorze Tegra, ale zgodnej wyłącznie z aplikacjami dostępnymi w ubogim i męczącym w programowaniu Sklepie Windows 8. Nowe wydanie Windows on ARM miało zlikwidować ten brak i dostarczyć zgodność z klasycznymi aplikacjami, przy okazji oferując zalety związane z wykorzystaniem energooszczędnych procesorów. Ale nic takiego się nie stało.
Aby zrozumieć dlaczego laptopy w architekturze ARM64 nie są dziś dobrem powszechnym musimy niestety zająć się nie sprzętem, a oprogramowaniem. Zasięg pecetów opartych o ARM jest ściśle związany z potocznym rozumieniem tego, czym jest "komputer z Windowsem" i czego należy od niego oczekiwać. A są to, jak się okazuje, potrzeby pokrywane przez taki sprzęt jedynie częściowo, co celem oszczędzenia sobie kłopotów, kończy się dokonaniem łatwego wyboru w postaci procesora x86.
Od peceta z Windows oczekujemy nie tylko dostępu do "chmury", chmurowych aplikacji, stron internetowych i prostych apletów. Innymi słowy, nasz komputer nie ma być czymś na kształt telefonu z klawiaturą. Wszak mimo spędzania większości czasu w przeglądarce internetowej, czasami zachodzi potrzeba użycia programu w innej postaci, niż strona WWW lub śliczna, uproszczona i dotykowa aplikacja użytkowa ze Sklepu. Innymi słowy, potrzebujemy uruchamiać programy EXE dostarczane w nieobostrzonej formie. Nie umiał tego Windows RT. Umie to robić Windows 10 dla ARM, ale siłą rzeczy nie może tego robić natywnie. W dodatku często nie umie tego robić wcale lub oferuje zauważalnie niską wydajność. Więc jak to w ogóle działa? W czym jest dziś problem i dlaczego początkowo było to w ogóle niemożliwe?
Zgodność
Zacznijmy od końca i zidentyfikujmy, co powstrzymywało klasyczne aplikacje przed działaniem na zapomnianym systemie Windows RT. Było to połączenie dwóch kwestii. Pierwszą była polityka: Microsoft przekonany o tym, że przyszłością są zamknięte ekosystemy, zdecydował się ograniczyć zbiór aplikacji tylko do oferty Sklepu. Oznaczało to, że na RT zadziałają wyłącznie nowe aplikacje, stworzone specjalnie dla Windows 8. Założenie to, oparte na przekonaniu, że Microsoft rozdaje karty na rynku konsumenckim, okazało się chybione i pogrążyło politykę parcia w stronę aplikacji Metro. Obecnie, z wielu powodów, całkowicie się z niego wycofano.
Drugim powodem były ograniczenia techniczne. Klasyczne aplikacje są kompilowane do kodu działającego na konkretnym procesorze i korzystającego z bibliotek również "celujących" w konkretny sprzęt. Taki kod nie jest przenośny: procesor po prostu nie rozumie instrukcji zapisanych w ten sposób i uruchomienie programu z innego świata jest niemożliwe. Dlatego Windows RT nie umiał uruchamiać klasycznych aplikacji. Sam system działał, ponieważ został w całości przekompilowany na procesor ARM. Było to możliwe, ponieważ jądro Windows, NTOSKRNL, jest napisane w języku C++ i od początku było projektowane jako przenośne między architekturami.
Emulacja
Problem ten miał zostać rozwiązany w systemie Windows 10. Aplikacje Win32 mają nie wymagać rekompilacji pod procesor ARM64 aby móc działać na ARM-owych komputerach. Jest to możliwe z wykorzystaniem warstwy emulacji. Środowisko uruchomieniowe x86 jest oferowane aplikacjom (32-bitowym) w całości: biblioteki, zarządzanie pamięcią i translacja rozkazów w locie składają się na wielką akcję udawania środowiska intelowskiego. Coś takiego brzmi jak fantastyka i niezwykle skomplikowany mechanizm. Czyżby Microsoft wynalazł coś nowego i genialnego? Nie do końca. Choć warstwie translacji x86-ARM nie sposób odmówić wyrafinowania, podobne mechanizmy znajdowały się w Windows już wcześniej.
Systemowy katalog "SysWoW64", którego nazwa jest skrótem od "System Libraries of classic Windows on Windows built for 64-bit" dostarcza właśnie taką warstwę. 32-bitowe aplikacje Windows nie są uruchamiane na dzisiejszych systemach "od razu", tylko przechodzą przez takie dorobione API. Rozkazy amd64 są "rozszerzeniem" standardy x86, a nie nową architekturą (jak niesławne Itanium), ale nie znaczy to, 32-bitowa aplikacja może sobie swobodnie sięgać do 64-bitowych struktur. Jest to jednak kod celujący w inny procesor i aby taki kod działał, potrzebna jest właśnie warstwa emulacji. WoW64 jest rzecz jasna mniej rozbudowane, niż translacja do ARM64, niemniej jego istnienie pokazuje, że wynalazek z emulowaniem cudzych środowisk nie jest nowy, zarówno w kwestii oprogramowania, jak i sprzętu. Zresztą nie tylko na Windows. Systemy z Linuksem w środku często korzystają z mechanizmów multiarch i multilib.
Wnętrzności
Warto przy okazji rozwiać pewne wątpliwości dotyczące samych aplikacji Win32. Określenie to, dotyczące klasycznych programów EXE spoza Sklepu, często kojarzy się z intelowskimi procesorami x86. Co za tym idzie, rekompilacja na procesor ARM64 miałaby sprawiać, że takie aplikacje przestają być aplikacjami Win32. Tymczasem to nie tak. Aplikacja Notatnik z systemu Windows 10 na procesorze Snapdragon to dalej aplikacja Win32... ale na ARM. Również Microsoft nie jest w tej kwestii w pełni konsekwentny. Określenie "Win32" dotyczy bardziej oprogramowania (API i biblioteki) niż sprzętu (x86 i ARM). Aplikacje Win32 na obie architektury korzystają z tego samego kontenera EXE, będącego spadkobiercą rozwiązania "Portable Executable" sprzed wielu, wielu lat. Windows jest na tyle rozbudowany i elastyczny, że kod budowany na inny procesor nie jest kompletnym "ciałem obcym", tylko zrozumiałym programem EXE. Po prostu niezdatnym do uruchomienia w danym ustroju.
Każe to zakładać, że konwersja programu między platformami nie powinna być tytanicznym wysiłkiem. I tak jest w istocie. Przyjrzyjmy się przykładom ze świata Visual Studio i załóżmy dwa projekty: aplikację UWP i aplikację konsolową.
Menedżer profili dla aplikacji UWP pozwala dodać nową architekturę i kompilować na nią nawet nie posiadając procesora ARM. Oczywiście, w takim przypadku działa opcja "Build", ale już nie "Build and run". Zamiast niej oferowana jest możliwość zdalnego uruchomienia zbudowanego kodu i podłączenia zdalnego odpluskwiacza 😜.
Aplikacja czysto konsolowa, czyli WinAPI dla NT i bez UWP, również może być skompilowana dla ARM. Microsoft wykazuje się tutaj pewną niekonsekwencją, bowiem środowisko WinAPI z Win32 dla procesorów x86 nazywa się... "Win32", czyli podpada pod klasyfikację "prawda, ale...". Tak zbudowana aplikacja, bez konieczności sięgania po UWP, pozwala przebudować kod na natywną platformę Windows on ARM i uniknąć stosowania warstwy emulacji, obniżającej wydajność. Teoretycznie więc, aby dostarczyć swój program dla ARM wystarczy tylko kilka kliknięć. Ale raczej nie przełoży się to na rychły wysyp natywnych aplikacji Win32 dla ARM.
Każdy z wyprodukowanych plików binarnych jest w formacie PE. Każdy Windows (oraz wiele wersji OS/2!) rozumie kod zapakowany w taki kontener. Możemy dzięki temu zobaczyć, jak wiele daje uniezależnienie systemu operacyjnego od platformy docelowej. Dziś jest to oczywistość, ale historia Windows pokazuje, że aby zaimplementować oczywistości, trzeba najpierw popełnić niemało drogich błędów.
Jakość
Ten optymistyczny scenariusz zakłada, że wszyscy twórcy aplikacji grzecznie przebudują swoje programy tak, by działały na platformie ARM. Odkurzą swój kod, wezmą najnowszą wersję Visual Studio, rozwiążą wszystkie pomniejsze problemy i za darmo zbudują wariant EXE dla nowej architektury. Szanse na taki scenariusz są bardzo, bardzo niskie. W praktyce, mimo całego wytężonego wysiłku, oczekiwanie takiej inicjatywy od programistów niewiele różni się od podejścia z Windows 8, gdzie nie kazano ludziom przebudowywać swoich aplikacji, ale pisać zupełnie nowe. To niewątpliwie awans, ale dalej spory problem.
Jak zwykle, wystarczy brak jednej aplikacji, żeby cały plan wziął w łeb. Nietrudno taką znaleźć, nawet przy założeniu, że komputery z Windows on ARM mają być "w pełni konsumenckie", co miałoby z definicji oznaczać brak aplikacji wysoce profesjonalnych. Jest nią bowiem Google Chrome. Wersja dla ARM nie jest jeszcze gotowa, nowy Edge też nie jest jeszcze gotowy, 64-bitowa x86 wersja w ogóle się nie uruchomi, a 32-bitowa jest chwilami mocno niewydajna. Na cóż nam te wszystkie rozwiązania "always-connected LTE" i wysoka energooszczędność, skoro Windows on ARM tak prędko może się okazać jedynie dziwną wariacją na temat Windows, a nie jego pełnoprawnym zamiennikiem.
Przyszłość
Ten sam problem miał Windows RT. Jego powstanie było dowodem na czystość kodu Windows i jego łatwą przenośność, co robiło wrażenie po latach od zamordowania Okien na alternatywnych architekturach. Podobnie warstwa translacji x86 do ARM robi niewątpliwe wrażenie, a wysiłek włożony w ułatwienie migracji projektów Visual Studio na inne platformy jest nie do przecenienia. Ale to wszystko nie jest konkurs na to, kto ma rację ani science fair, gdzie nagradzane są najciekawsze i najbardziej wymagające intelektualnie rozwiązania. Klienci wybiorą po prostu to, co działa. A będzie to układ Intela.
Microsoft próbuje jednak ponownie wskrzesić pomysł pochodzący z pierwszej linii urządzeń Surface: podstawowy Surface z ARM i zaawansowany Surface Pro z Intelem. Sukces wersji ARM prawdopodobnie przypieczętowałby los linii Surface Go, opartej na układzie Pentium i istniejącej niewątpliwie tylko dlatego, że Windows na Snapdragonach zawiódł. Czy nowa-stara polityka sprawdzi się siedem lat później? Przekonamy się już drugiego października, kiedy to Microsoft zaprezentuje siódmą linię swoich tabletów.
Czy planujecie zakup urządzeń opartych o układ ARM? Dajcie nam znać w komentarzach!