Jön a Wayland explicit sync – De mire lesz jó?

Manapság nagy a sürgés-forgás a Wayland körül. Az egyik legnagyobb újdonság az ún. explicit sync bevezetése. Ebben a rövid írásban körbejárom, hogy mit is jelent ez számunka.

Wayland ikon
Wayland ikon

Manapság nagy a sürgés-forgás a Wayland körül. Az egyik legnagyobb újdonság az ún. explicit sync bevezetése. Ebben a rövid írásban körbejárom, hogy mit is jelent ez számunka.

Mi ez a szinkronizáció és mire kell?

Amikor az alkalmazás meg akar jeleníteni valamit (renderelni akar), akkor az nem azonnali dolog. Először is egy listát készít a végrehajtandó OpenGL vagy Vulkan parancsokról, amit átad a videokártyának, hogy hajtsa végre őket, amikor ráér.

Erre azért van szükség, hogy a processzornak ne kelljen arra várnia, hogy a GPU egyesével végrehajtsa az összes utasítást, hanem közben dolgozhasson valami máson (pl. a GPU-nak szánt következő utasításokon), magyarul nő a teljesítmény.

A gyakorlatban ez úgy néz ki, hogy rengeteg dolog történik: egy folyamat épp egy képet készít, amit egy másik át akar alakítani, aminek az eredményét egy harmadik visszatöltené a CPU-nak, hogy aztán az kimenthesse a lemezre. Ha mindez szinkronizáció nélkül történne, akkor előfordulhatna, hogy egy félkész képet sikerül kimenteni vagy éppen semmit, mert a képkészítés még el sem kezdődött.

Implicit szinkronizáció

Ez a régi módszer, amit a hagyományos grafikus API-k (pl. OpenGL) használnak a szinkronizációhoz. Ilyenkor az alkalmazás nem tud arról, hogy mi történik a háttérben, a kernel és/vagy a grafikus illesztőprogram végzi a szinkronizációt. Figyelik, hogy az alkalmazás milyen parancsokat küld a GPU felé, hogy azok melyik képre vonatkoznak, milyen egyéb parancssorozatoknak kell a végrehajtása előtt lefutniuk stb. Ennek akár az is lehet a vége, hogy az alkalmazást várakoztatni kell, hiszen meg kell várni, míg elkészül az eredmények.

Linux alatt az alkalmazások az úgynevezett dma buffer alrendszeren keresztül cserélgetik egymás között a képeket. Ezt használja pl. a Wayland alkalmazások és a kompozíciós ablakkezelő (compositor) közti kommunikációjához is.

A dma buffer (dma-buf) egy keretrendszer a Linux kernelben, amelyen keresztül a különböző illesztőprogramok és alrendszerek adatokat (puffereket) oszthatnak meg egymással és tehetnek a hardvernek elérhetővé DMA-n (Direct Memory Access) keresztül. Továbbá lehetővé teszi az aszinkron eszközök szinkronizált elérését is.

Az implicit szinkronizáció használatakor, amikor a kompozíciós ablakkezelő olvasni akar az alkalmazás pufferéből, de az még nincs kész a munkával, akkor a kernel várakoztatja, míg az befejezi a megjelenítést.

Ennek a megközelítésnek az egyik előnye, hogy könnyen lehet jól működő alkalmazásokat írni, mivel minden feladatot átvállal a kernel. Viszont mivel ez az egész folyamat az alkalmazás számára láthatatlan – és befolyásolhatatlan –, így bizonyos esetekben problémákat okoz. Wayland szempontból a legrelevánsabb, hogy az alkalmazás nem tudja, hogy a saját megjelenítése mely másik programhoz szinkronizálódott, illetve előfordulhat, hogy olyan feladatok elkészültét kell megvárnia, amiknek semmi köze az éppen futó folyamatnak.

Ez egy jó ideje probléma a Wayland kompozíciós ablakkezelőknél: az alkalmazás megjelenítésekor lehet, hogy egy olyan képet akarna az ablakkezelő megjeleníteni az alkalmazásról, amin még dolgozik a GPU, tehát nincs kész, ahelyett hogy egy régebbit mutatna róla. A szinkronizálás miatt a kernel várakoztatja az ablakkezelőt, ami miatt előfordulhatnak komolyabb lassulások, és döcögős felhasználói élmény. De ha a régebbit mutatná, akkor minden gyorsabb lehetne.

A probléma nem új keletű, és kb. két éve megoldás is született rá: https://www.collabora.com/news-and-blog/blog/2022/06/09/bridging-the-synchronization-gap-on-linux/. A Collabora támogatásával született egyféle implicit-explicit szinkronizációs megoldás. Működése részletesen bemutatásra került itt: https://blogs.gnome.org/shell-dev/2023/03/30/ensuring-steady-frame-rates-with-gpu-intensive-clients/

Explicit szinkronizáció

Ahogy a neve is sugallja, ebben az esetben az alkalmazás ahelyett, hogy a kernelre vagy a grafikus illesztőprogramra támaszkodna a szinkronizációs döntésekben, konkrétan maga dönt arról, hogy mely feladatokhoz akar szinkronizálódni, és a döntését közli a megfelelő komponenssel is (ez lehet az illesztőprogram, kernel, ablakkezelő vagy egy másik alkalmazás).

Alkalmazás oldalon a Vulkan API explicit szinkronizációt használ, a Wayland protokoll pedig OpenGL és Vulkan illesztőprogramok segítségével szinkronizál a Wayland kompozíciós ablakkezelővel.

Az explicit szinkronizáció előtt is volt már egy (fél)megoldás (https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/unstable/linux-explicit-synchronization/linux-explicit-synchronization-unstable-v1.xml), de annak az elsődleges problémája, hogy a szinkronizációhoz előbb egy GPU parancsot kellett küldeni a kernelnek. Az új megoldással anélkül lehet szinkronizációs primitíveket létrehozni, hogy előtte munkát kellett volna küldeni a grafikus processzornak, tehát – elméletben – egy kicsivel több teljesítmény is kifacsarható a hardverből.

Az explicit szinkronizáció nem csak az „akaratlan” szinkronizációt kerüli el, hanem valamennyi teljesítménynövekedéssel is jár, hiszen ennyivel is kevesebb munkája van a grafikus illesztőprogramnak, nem kell „kitalálnia”, hogy mit mihez kössön, mert megmondják neki. Ugyanakkor ez a teljesítménynövekedés nem jelentős. Bizonyos különleges esetekben lehet, hogy az implicit szinkronizáció fogta vissza a teljesítményt, de sokkal nagyobb a valószínűsége annak, hogy észre sem fogod venni a változást.

Már megint csak a felhajtás?

Tehát a legtöbb probléma a kompozíciós ablakkezelőben meg lett oldva, a teljesítménynövekedés pedig minimális, akkor mégis miért pörög ezen mindenki?

A válasz egyszerű: A zárt forrású Nvidia illesztőprogram nem támogatja az implicit szinkronizációt. A fentebb említett félmegoldást pedig se a Waylanddel használható kompozíciós ablakkezelők többsége, se pedig az Nvidia illesztőprogramja nem szívleli. Emiatt az említett gyártó hardvereit használók villódzásokat és képkocka elhelyezési gondokat tapasztalhatnak.

Persze az Nvidia illesztőprogram megpróbálja saját hatáskörben orvosolni a problémát, de csak kezeli, megoldani nem tudja:

  • Wayland alatt lényegében sorba állítja a feladatokat, megvárja,  amíg elkészül az adott kép és csak utána szól a Waylandnek. Ez szembe megy azzal, ahogy a Wayland működik, ennek megfelelően kisebb-nagyobb problémákat, akár összeomlásokat is okozhat.
  • X11 alatt is megvárja a kép elkészültét, amit ha az Xwayland egy Nvidia GPU segítségével másol át, akkor problémák jelentkezhetnek.

Rengeteg beszélgetés olvasható arról, hogy egyeseket folyamatosan sújtanak az említett problémák, míg másokat szinte sosem. Itt az a gond, hogy nem determinisztikus, mikor jelentkezik a szinkronizációs hiba és mikor nem. Sok tényezős egyenletről beszélünk, így számít, hogy milyen processzort és grafikus kártyát használsz, az illesztőprogramok verziója, a kernel, a kompozíciós ablakkezelő és így tovább. Próbáld meg eldönteni, hogy épp mi okozza a bajokat.

Amint az explicit szinkronizáció implementálva lesz az Xwaylandben (a májusban megjelenő 24.1 elvileg már tartalmazni fogja), a széteső képek és egyéb a rossz szinkronizáció miatt jelentkező problémák remélhetőleg a múlt emlékei lesznek. Ezzel pedig az Nvidia grafikuskártyával rendelkező felhasználók legnagyobb akadálya is elhárult a Waylandre történő átállás elől.

Az írás jelentős mértékben támaszkodik Xaver Hugl Explicit sync című blogbejegyzésére.