sâmbătă, 1 martie 2014

De ce "Wine Is Not an Emulator"

Wine, despre care am mai scris pe aici, este un program-minune care permite rularea de aplicaţii Windows pe Linux. Deşi compatibilitatea nu este asigurată în proporţie de 100%, ai mari şanse ca jocul sau programul tău preferat din Windows să ruleze pe Linux prin intermediul Wine, uneori chiar "la perfecţie" şi chiar mai rapid decât pe Windows.

Dar cum e posibil ca un program care nu e scris pentru Linux să funcţioneze totuşi pe acesta, cum e posibil să funcţioneze chiar mai bine şi mai ales de ce toată lumea zice că Wine nu este un emulator?

1. Ce sunt emulatoarele
Există (suficient de) multe arhitecturi pe care se bazează sistemele informatice. Dacă citeşti aceste rânduri de pe un calculator sau laptop e foarte posibil ca acesta să fie unul IBM-based, cu procesor ce suportă setul de instrucţiuni x86. Acest set de instrucţiuni este o listă de "comenzi" pe care un procesor le înţelege. Evident, nu toate procesoarele sunt proiectate la fel, de aici venind şi multitudinea de seturi de instrucţiuni existente. Foarte probabil ca în momentul acesta să ai în buzunar sau undeva pe birou un telefon cu Android, care cel mai probabil foloseşte un procesor compatibil ARM, incompatibil cu procesoarele x86 (în caz că te-ai întrebat vreodată de ce nu poţi să pui Windows pe el, deşi are 1GB RAM şi procesor de 1,2 Ghz). Sau poate că atunci când erai mic ai avut o consolă de jocuri pe televizor, care din nou avea un procesor incompatibil cu x86-ul din calculatorul tău.

Emulatorul este un program ce creează o punte între două arhitecturi (de obicei, una client şi una gazdă). Cu ajutorul emulatoarelor pot fi executate programe proiectate pentru un tip de procesor, acesta preluând comenzile trimise de aceste programe şi translatându-le în comenzi specifice arhitecturii gazdă. Astfel programele rulate într-un emulator se simt "ca la ele acasă", deşi rulează de fapt pe o arhitectură străină lor. Marele dezavantaj e că această translatare nu se produce aşa, cu una, cu două, ci va necesita putere de calcul şi va fi mai lentă decât sistemul pe care îl emulează. Trebuie menţionat că emulatoarele nu se rezumă doar la traducerea acestor instrucţiuni, majoritatea punând la dispoziţie sisteme virtuale complete, cu plăci de sunet, de reţea sau plăci video. Astfel este posibil să ai un calculator virtual instalat în calculatorul tău, adică fix ceea ce fac programe de genul VirtualBox.

2. Cum rulează programele într-un calculator
După cum scriam mai sus, programele (în special cele compilate) conţin instrucţiuni specifice unei anumite arhitecturi. Totuşi ştim destul de bine că nu poţi rula pur şi simplu programe Windows pe Linux, deşi amândouă sisteme de operare funcţionează pe aceleaşi arhitecturi, altfel nu am mai auzi atât de des spunându-se "dar pe Linux nu sunt jocuri". Pe lângă aceste instrucţiuni, programele mai apelează şi la librării (unii preferă să le numească biblioteci). Aceste librării pot fi numite naiv "programe ajutătoare", conţinând rutine software ce scutesc programatorii de la reinventarea roţii (de asemenea se ştie foarte bine că programatorii tind să fie cam... leneşi). De exemplu, pentru afişarea unei imagini JPEG un program trebuie să "înţeleagă" conţinutul binar al fişierului şi apoi să îl translateze în valori de culori pe care, mai apoi, să le afişeze pe ecran. Deoarece e imposibil pentru un programator să cunoască structura atâtor formate de fişiere (.bmp, .gif, .jpg, .png, .tiff, etc) iar scrierea unui astfel de algoritm ar lua mult timp (şi ar însemna să reinventezi roata pentru fiecare program de vizualizat imagini), cel mai adesea aceştia vor apela la librării care se vor ocupa de decodificarea fişierelor şi convertirea acestora în culori ce vor fi afişate pe ecran şi care vor forma o imagine.

Aproape toate programele pentru calculator apelează la aceste librării pentru a face ceva. Ba mai mult, chiar şi librăriile apelează, la rândul lor, alte librării pentru a duce la capăt anumite sarcini. Aceste librării conţin nişte API-uri, adică un set de funcţii ce pot fi apelate din programele ce le încorporează. De exemplu, pentru a citi un fişier JPEG şi a obţine valorile pixelilor din aceasta, un vizualizator de imagini ar apela metoda "decodeJPEG()" pusă la dispoziţie de către librăria sa de decodificare a imaginilor JPEG. O listă de astfel de metode puse la dispoziţia programatorului poartă denumirea de API. Toate programele scrie pentru Windows folosesc măcar WinApi. Acest API este pus la dispoziţie de însăşi sistemul de operare Windows şi conţine o multitudine de funcţii, începând de la cele pentru desenarea interfeţei grafice până la exotisme gen accesarea şi configurarea dispozitivelor hardware din sistem. Evident, WinApi este parte integrată în Windows şi nu este disponibilă pentru alte sisteme de operare. De asta programele de Windows nu vor funcţiona pe Linux, DOS sau alte sisteme de operare.

3. Ce face Wine
Wine este, de fapt, o implementare a WinApi pe Linux (şi nu numai). Asta înseamnă că Wine pune la dispoziţie un set de API-uri asemănător lui WinApi şi care răspunde apelurilor făcute de aplicaţiile ce folosesc WinApi în acelaşi fel cum se întâmplă pe Windows. Wine este un program compilat pentru Linux (şi nu numai), ceea ce înseamnă că API-ul pe care îl oferă se va executa direct în acest sistem de operare, în mod nativ, fără a fi necesare operaţiuni specifice emulatoarelor. S-ar putea spune, astfel, că acele programe de Windows rulează, de fapt, nativ pe Linux! Putem afirma în acest fel, deşi forţat, că Wine este pentru programele Windows ce este GTK pentru GEdit.

Astfel, din cîte puteţi observa, în cazul lui Wine nu se produce o translatare aşa cum se întâmplă cu emulatoarele, de aici venind şi viteza cu care aplicaţiile Windows rulează pe Linux. Spuneam la început că aplicaţiile pentru Windows pot rula chiar mai rapid pe Linux, motivele fiind următoarele:

  • Calitatea implementării unor API-uri poate fi mai bună în Wine decât în Windows. Creşterea performanţei în aplicaţii este o chestiune suficient de "hard-core" chiar şi pentru cei de la Microsoft şi poate fi influenţată de factori externi (dependinţe de alte librării, etc.), aşa că este foarte probabil ca Wine să fie mai rapid în unele locuri decât WinApi.
  • Linux este simţitor mai rapid decât Windows. Aici sunt multe chestiuni tehnice de discutat iar părerile sunt oricum împărţite, dar opinia generală este că kernelul Linux pare a fi mai "fâşneţ" decât cel din Windows. Valve ar fi ales Linux pentru consolele lor datorită latenţelor mici de care se bucură acesta, pe lângă faptul că poate fi personalizat cu uşurinţă.
  • Unele API-uri din Windows nu sunt implementate în Wine. De fapt, multe lucruri din WinApi lipsesc din Wine. Asta făcea ca GTA San Andreas, de exemplu, să se fi încărcat de două ori mai repede pe Linux decât pe Windows deoarece la unele apeluri Wine zicea doar "pas", în timp ce Windows procesa la greu comenzile primite.
Închei aici, cu speranţa că acest articol a fost suficient de lizibil şi a adus, totodată, lămuriri pentru "De ce Wine Is Not an Emulator". Pentru orice alte detalii sau corectări vă stă la dispoziţie secţiunea de comentarii, la care vă recomand cu căldură să apelaţi de fiecare dată când aveţi nevoie.


2 comentarii :

Anonim spunea...

Foarte fain articolul!
Intrebare: E posibil, in felul asta, sa scriu cod WinAPI pe linux doar link-and programul meu de WinAPI cu Wine?

Uau, chiar nu m-am gandit niciodata la cum e implementat Wine si m-ai facut curios. Desi toata lumea stie cat de spurcat e WinAPI in comparatie cu POSIX as incerca macar un "Hello World" odata sa vad cum merge :D

Ovidiu Niţan spunea...

Da, în modul ideal poţi porta o aplicaţie scrisă pentru Windows în Linux doar compilând-o cu http://wiki.winehq.org/Winelib. În felul acesta obţii un binar pentru Linux care nu mai trebuie executat prin intermediul Wine (deşi încă foloseşte librăriile acestuia).

Nu ştiu însă în ce stadiu e winelib, wiki-ul celor de la Wine spune că ar exista chiar proiecte funcţionabile compilate cu acesta.