Browse Source

nuovo post

Elia Argentieri 10 months ago
parent
commit
6bee8a6dd1
1 changed files with 346 additions and 0 deletions
  1. 346
    0
      content/blog/linux-gpu.md

+ 346
- 0
content/blog/linux-gpu.md View File

@@ -0,0 +1,346 @@
1
++++
2
+title = "Linux e GPU"
3
+draft = false
4
+slug = "linux-e-gpu"
5
+date = "2018-01-04T18:00:00"
6
+categorie = ["Linux", "Software Libero", "Grafica"]
7
+image = "https://gmg.elinvention.ovh/mgoblin_media/media_entries/187/mesa.png"
8
++++
9
+
10
+Oggi vi parlo di schede grafiche nel mondo GNU/Linux, in particolare delle
11
+schede AMD. Il motivo per cui mi concentro sull'AMD è semplice: è l'unica
12
+azienda che ha preso seriamente il settore Linux Desktop/Gaming. Purtroppo Intel
13
+non produce hardware sufficientemente potente per lo scopo, mentre NVIDIA è
14
+pensa solo a impedire agli utenti di eseguire un software diverso da quello che
15
+hanno deciso loro, ostacolando in tutti i modi il progetto nouveau. Non a caso
16
+il [signor Linus Torvalds si è già espresso limpidamente a riguardo][torvalds].
17
+
18
+In questo articolo introdurrò i molti nomi che vengono continuamente citati
19
+quando si parla di driver open source, ma non fatevi intimorire.
20
+
21
+Su Linux la gestione della scheda grafica o di altri processori accelerati, è,
22
+vista la complessità, organizzata in moduli e in livelli. Un certo numero di
23
+moduli che cooperano possono esporre ad un livello superiore un insieme di
24
+funzionalità tramite delle API (Application Programming Interface). Più che ci
25
+allontaniamo dal livello di partenza (l'hardware), maggiore è il livello di
26
+astrazione. Esaminiamo (superficialmente) i vari livelli per arrivare alle
27
+nostre finestre interattive con tanto di puntatore, icone colorate e animazioni
28
+così complesse che con meno potenza di calcolo ci sono andati sulla Luna :D.
29
+
30
+<!--more-->
31
+
32
+![](https://upload.wikimedia.org/wikipedia/commons/9/99/Linux_kernel_and_OpenGL_video_games.svg)
33
+
34
+# Livello 0: hardware
35
+
36
+Come ho già detto, l'hardware è il livello di partenza, senza il quale non si
37
+porrebbero tutti questi problemi... Ovviamente è costituito da almeno una CPU e,
38
+solitamente, almeno una GPU. Le varie unità comunicano tra di loro mediante un
39
+bus, un sistema di comunicazione ad alta velocità arbitrato. La CPU ha accesso
40
+alla memoria RAM principale, mentre la GPU può avere accesso ad una memoria ad
41
+essa riservata o condividere la RAM con la CPU, in base al tipo di GPU (discreta
42
+o integrata).
43
+
44
+A tal proposito l'AMD, da qualche anno, propone l'[HSA]
45
+(Heterogeneous System Architecture), un insieme di specifiche per l'integrazione
46
+di CPU e GPU sullo stesso bus, in modo che condividano la memoria e i lavori da
47
+eseguire, in modo da ridurre l'inevitabile latenza di comunicazione tra CPU e
48
+GPU.
49
+
50
+La necessità di una GPU separata dalla CPU sorge dal fatto che i programmi
51
+grafici (specialmente quelli 3D), devono eseguire ripetutamente un certo insieme
52
+di operazioni (nel caso 3D calcoli di algebra lineare, come la moltiplicazione
53
+di matrici).
54
+Per rendere l'esecuzione più efficiente, la GPU è armata di hardware che esegue,
55
+in pochi cicli di clock, operazioni che altrimenti avrebbero richiesto numerose
56
+istruzioni macchina della CPU. In questo senso si parla di
57
+accelerazione grafica. Infatti esiste anche l'accelerazione crittografica
58
+che è inclusa in tutte le CPU moderne ed è fondamentale sui server. Esiste anche
59
+l'accelerazione audio fornita dalle schede audio per calcoli di DSP
60
+(Digital Signal Processing).
61
+
62
+# Livello 1: kernel
63
+
64
+Il Kernel è il componente fondamentale di ogni sistema operativo ed il suo scopo
65
+principale è quello di arbitrare l'accesso alle risorse hardware da parte dei
66
+processi, garantendo un compromesso fra prestazioni e sicurezza.
67
+
68
+I nostri bei programmi grafici colorati, per accendere tutti quei pixel, devono
69
+tenere in memoria il colore di ogni pixel su schermo. L'area di memoria, di
70
+solito della GPU, predisposta per questo scopo si chiama tradizionalmente
71
+framebuffer.
72
+Ad esempio se ho uno schermo con risoluzione 800×600, avrò bisogno di avere in
73
+memoria 800×600 = 480000 pixel. Ogni pixel di solito ha una profondità di colore
74
+di 24bit (RGB -> 1 byte per il rosso, 1 per il verde e 1 per il blu = 3 byte =
75
+24 bit), quindi la dimensione del framebuffer in byte sarà
76
+800 × 600 × 3 = 1440000 byte ≃ 1.4 MB.
77
+Uno schermo 4K ha bisogno di un framebuffer di
78
+4096 × 2160 × 3 = 26542080 ≃ 25 MB.
79
+
80
+In realtà la situazione è più complessa e, solitamente, si usano più di un
81
+framebuffer, ad esempio nella tecnica chiamata double buffering, si usano 2
82
+framebuffer: uno contiene il frame che la GPU sta calcolando, l'altro contiene
83
+il frame precedentemente completato. Quando la GPU finisce di calcolare, i
84
+framebuffer vengono scambiati, così che il frame che viene inviato al monitor
85
+sia sempre completo, evitando il cosidetto "tearing" (lo schermo visualizza metà
86
+del vecchio frame e metà del nuovo).
87
+
88
+Ora più processi che scrivono nel framebuffer, inevitabilmente causano problemi,
89
+ad esempio su schermo si vedrà chi arriva a sovrascrivere per ultimo.
90
+Per quanto riguarda il kernel Linux, inizialmente, c'erano solo le semplici API
91
+FBDEV (FrameBuffer DEVice), che consentivano a più processi di condividere un
92
+framebuffer virtuale nella RAM. Tuttavia tali API non erano state progettate per
93
+supportare l'accelerazione hardware. Il progetto [DirectFB] altro non era che la
94
+modifica di FBDEV per consentire l'accelerazione grafica, ma non ha avuto fortuna.
95
+
96
+Successivamente (prima di DirectFB) fu introdotto in Linux il sottosistema
97
+[DRM (Direct Rendering Manager)][DRM], che espone delle API che permettono ai
98
+processi in spazio utente di mandare comandi direttamente alla GPU, gestendo i
99
+problemi di concorrenza tra processi.
100
+
101
+DRM ha molti driver, cioè codice che dipende da quale dispositivo stiamo
102
+utilizzando, tra i quali: radeon, i915, nouveau, amdgpu, virtio, vc4, msm e altri.
103
+L'AMD ha 2 driver DRM: il vecchio radeon e il nuovo amdgpu, entrambi di ottima
104
+qualità. Anche il driver i915 è in ottima forma. Purtroppo ciò non si applica
105
+agli altri driver, il cui grado di qualità varia molto fino ad arrivare al
106
+pessimo, quasi inutilizzabile, visto che queste grandi aziende si tengono per se
107
+tutta la documentazione rilevante dei prodotti che vendono.
108
+
109
+Un altro modulo importante è KMS (Kernel ModeSetting) e gestisce la
110
+comunicazione a basso livello con i monitor. Ad esempio si occupa di codificare
111
+il contenuto del framebuffer per inviarlo al monitor.
112
+
113
+# Livello 2: libdrm (DRM library)
114
+
115
+Lo spazio utente, invece di interagire direttamente con le API di DRM, utilizza
116
+la libreria libdrm, che ne facilita l'accesso e permette di riutilizzare il
117
+codice, che altrimenti andrebbe ripetuto in ogni programma. Anche libdrm è
118
+composta da una parte comune e una parte che dipende dall'architettura della
119
+scheda grafica.
120
+Abbiamo, infatti i vari libdrm_radeon, libdrm_amdgpu, libdrm_intel,
121
+libdrm_nouveau e così via, che potenzialmente implementano funzionalità
122
+aggiuntive, non presenti nella parte comune.
123
+
124
+# Livello 3: Mesa3D
125
+
126
+Per quanto detto fin'ora, uno sviluppatore che vuole pubblicare una applicazione
127
+grafica dovrebbe scriversi del codice specifico per ogni piattaforma: dovrebbe
128
+usare le API di Linux, Windows, Android e così via, nel suo programma.
129
+
130
+A questo punto entra in gioco [Mesa3D], nata come implementazione open source
131
+delle API OpenGL. Mesa interagisce con libdrm per fornire le sue API più
132
+astratte e indipendenti dal tipo di acceleratore grafico.
133
+OpenGL è ben nota perché è l'API multipiattaforma per eccellenza ed è supportata
134
+da tutti i sistemi operativi principali (Linux, Mac, Windows e pure i BSD).
135
+Col passare degli anni, Mesa ha aggiunto il supporto a molte altre API, quali:
136
+OpenGL ES, EGL, OpenCL e Vulkan.
137
+
138
+Sulle distribuzioni GNU/Linux viene distribuita nell'installazione di base per
139
+desktop.
140
+Lo sviluppo di Mesa è cresciuto esponenzialmente nel corso degli anni ed
141
+ormai ha poco a cui invidiare ad altre soluzioni proprietarie, specialmente
142
+quando si parla di schede grafiche AMD o Intel (ribadisco: [NVIDIA no][torvalds]).
143
+
144
+Per mettere in comunicazione le applicazioni grafiche con l'hardware accelerato,
145
+è stato introdotto in Mesa e nel kernel (parte di DRM) l'infrastruttura [DRI]
146
+(Direct Rendering Infrastructure).
147
+
148
+Come libdrm, anche Mesa ha del codice specifico ad ogni acceleratore:
149
+
150
+| Driver    | Schede video         |
151
+|-----------|----------------------|
152
+| r600      | AMD fino a TeraScale |
153
+| radeonsi  | AMD architettura GCN |
154
+| i965      | Intel                |
155
+| nv50      | NVIDIA fino a Tesla  |
156
+| nvc0      | NVIDIA da Fermi      |
157
+| freedreno | Qualcomm             |
158
+| softpipe  | software             |
159
+| llvmpipe  | software             |
160
+| swr       | software             |
161
+
162
+![Gallium3D](https://upload.wikimedia.org/wikipedia/commons/f/fe/Gallium3D_example_matrix.svg)
163
+
164
+Con l'eccezione del driver i965 dell'Intel, che viene considerato un driver
165
+"classico" o DRI-style, tutti i driver condividono una parte del codice,
166
+utilizzando un'infrastruttura comune chiamata Gallium3D, progettata per
167
+facilitare la scrittura di nuovi driver Mesa. Il driver i965 è stato scritto
168
+prima che venisse introdotto Gallium3D e per vari motivi non è stato portato.
169
+
170
+![Gallium3D vs DRI](https://upload.wikimedia.org/wikipedia/commons/c/cf/Gallium3D_vs_DRI_graphics_driver_model.svg)
171
+
172
+I driver software (**softpipe**, **llvmpipe** e **swr**) implementano OpenGL
173
+senza accelerazione da parte della GPU.
174
+
175
+Softpipe è un driver non molto performante, quindi è stato "potenziato"
176
+utilizzando il compilatore [LLVM], ottenendo llvmpipe. Nel caso in cui si
177
+utilizzi un pc senza scheda grafica, di default Mesa renderizza usando llvmpipe.
178
+swr, invece, è più recente ed è riservato a CPU Intel che hanno particolari
179
+istruzioni macchina accelerate.
180
+
181
+Gallium3D fornisce inoltre una comoda HUD che permette di plottare su schermo
182
+vari grafici relativi alle performance, al carico, alla temperatura e velocità
183
+delle ventole. Basta settare la variabile di ambiente GALLIUM_HUD e lanciare
184
+l'applicazione grafica che vogliamo monitorare.
185
+Ad esempio `GALLIUM_HUD='fps' glxgears` lancia glxgears mostrando un grafico
186
+degli fps.
187
+
188
+È possibile avere una panoramica grafica dello stato dei vari driver Mesa dal
189
+sito [mesamatrix.net].
190
+
191
+# Livello 4: X, Wayland o Mir
192
+
193
+![](https://upload.wikimedia.org/wikipedia/commons/2/2d/The_Linux_Graphics_Stack_and_glamor.svg)
194
+
195
+Su questo livello troviamo ben 3 alternative: il tradizionale X,
196
+l'emergente compositore Wayland e Mir, server creato da Canonical per Ubuntu,
197
+ma non andato in porto. Tutte le distribuzioni, compreso Ubuntu, stanno
198
+attualmente completando la transizione da X a Wayland. Il server X è un software
199
+che ha origini molto antiche, per quanto riguarda l'informatica.
200
+La sua architettura, seppur rivista più volte, è piuttosto datata ed è fonte di
201
+numerosi problemi di sicurezza e prestazioni per i desktop Linux.
202
+
203
+Il server X ha nuovamente una parte DIX (Device Independent X) e una parte DDX
204
+(Device Dependent X). Questa dipendenza dal dispositivo è rimasta per ragioni
205
+storiche. Prima dell'avvento di DRM, infatti, era la parte DDX a dover
206
+effettuare il mode setting, infatti si parlava di UMS (User Mode Setting) e il
207
+server X andava eseguito con i privilegi di root!
208
+Oggi è disponibile il DDX xf86-video-modesetting, che è generico in quanto
209
+accelera il 2D usando GLAMOR che traduce le primitive 2D in operazioni OpenGL,
210
+rendendo obsoleto il concetto di DDX.
211
+
212
+![Wayland](https://upload.wikimedia.org/wikipedia/commons/a/a7/Wayland_display_server_protocol.svg)
213
+
214
+Le idee chieve dietro al nuovo sistema Wayland sono:
215
+
216
+- specifica del protocollo Wayland
217
+- libwayland-server, implementazione in C lato server (detto anche compositore,
218
+ad esempio: Weston o GNOME Shell) del protocollo
219
+- libwayland-client, implementazione lato client (ad esempio GTK o Qt) in C del
220
+protocollo
221
+- il compositore compone i buffer delle finestre delle varie applicazioni
222
+- ogni finestra ha un suo buffer e non può vedere i buffer delle altre finestre,
223
+a meno che non lo richieda al compositore (che potrebbe negare la richiesta
224
+per motivi di sicurezza)
225
+- input delle periferiche gestito con libinput (utente) e evdev (kernel)
226
+- accelerazione grafica diretta tramite [EGL] sia per il compositore che per le
227
+finestre dei client (non sono necessari i DDX)
228
+
229
+# Livello 5: Toolkit grafico (GTK, Qt, SDL, ...)
230
+
231
+![UI toolkit](https://upload.wikimedia.org/wikipedia/commons/7/7b/Free_and_open-source-software_display_servers_and_UI_toolkits.svg)
232
+
233
+Quando si vuole scrivere un nuovo programma con interfaccia grafica, solitamente
234
+si utilizzano delle API che semplificano notevolmente lo sviluppo e garantiscono
235
+l'uniformità a livello sia visivo che operativo dell'applicazione con tutte le
236
+altre applicazioni installate sul sistema. L'annoso compito viene svolto da un
237
+toolkit grafico. I più conosciuti sono GTK, Qt e SDL, tutte librerie
238
+multipiattaforma.
239
+
240
+GTK, sorprendentemente, sta per GIMP ToolKit, infatti inizialmente faceva parte
241
+di GIMP, il noto programma di manipolazione di immagini! Solo successivamente è
242
+stato separato ed è diventato il toolkit usato da GNOME, il famoso ambiente
243
+grafico.
244
+
245
+Qt invece viene utilizzato da KDE, altro ben noto ambiente grafico in
246
+competizione con GNOME.
247
+
248
+SDL (Simple DirectMedia Layer) è una libreria multipiattaforma che consente
249
+l'accesso a basso livello a mouse, tastiera, audio e scheda grafica tramite
250
+OpenGL o DirectX e viene utilizzata dalla maggioranza dei giochi.
251
+
252
+I programmi che fanno uso di questi toolkit non devono preoccuparsi se vengono
253
+eseguiti su ambiente Wayland o X o su un altro sistema operativo, perché è
254
+proprio il compito del toolkit quello di astrarre da tutto ciò che sta al di
255
+sotto.
256
+
257
+# Fine
258
+
259
+Incredibilmente, dopo tutti questi passaggi, la nostra applicazione GTK/OpenGL
260
+(inserisci qui una API supportata), può tranquillamente renderizzare in 3D sia
261
+in finestra che a schermo intero a 60FPS (se non di più)!
262
+
263
+# Appendice 1: driver schede AMD
264
+
265
+Eh si stavolta ho pure l'appendice!
266
+Ecco una tabella che vi mostra quali driver state utilizzando se avete schede AMD:
267
+
268
+| Architettura           | DRM(Kernel) | OpenGL(Mesa) | X.org             |
269
+|------------------------|-------------|--------------|-------------------|
270
+| TeraScale e precedenti | radeon      | r600         | xf86-video-ati    |
271
+| GCN 1.0 e 1.1          | radeon      | radeonsi     | xf86-video-ati    |
272
+| GCN 1.0 e 1.1          | amdgpu      | radeonsi     | xf86-video-amdgpu |
273
+| GCN 1.2 e successive   | amdgpu      | radeonsi     | xf86-video-amdgpu |
274
+
275
+Nel caso GCN 1.0 e 1.1 ci sono due alternative: il vecchio driver radeon che è
276
+ancora il default, o il nuovo amdgpu (ormai conviene attivarlo). Se si ha una
277
+scheda GCN 1.0 basta passare al kernel i parametri
278
+`amdgpu.si_support=1 radeon.si_support=0`, mentre se è GCN 1.1
279
+`amdgpu.cik_support=1 radeon.cik_support=0` (testato su Linux 4.14).
280
+
281
+[Questa pagina di Wikipedia][amd] è utile per capirci qualcosa sul casino che ha
282
+fatto l'AMD con nomi visto che ogni scheda ha più di un nome commerciale e un
283
+solo nome in codice.
284
+
285
+# Appendice 2: compilare Mesa3D con meson
286
+
287
+Come si compila Mesa? Con [meson]!... eh dai non l'hanno fatto apposta...
288
+
289
+```
290
+# Il sorgente git pesa qualche centinaio di MB
291
+git clone git://anongit.freedesktop.org/mesa/mesa
292
+cd mesa
293
+
294
+# Configurazione di mesa da riempire con i driver che si desiderano
295
+# ad esempio -Dgallium-drivers=r600 o -Dgallium-drivers=radeonsi
296
+meson build -Dbuildtype=release -Dprefix=/opt/mesa-master \
297
+-Ddri-drivers= -Dgallium-drivers= -Dvulkan-drivers= \
298
+-Ddri3=true -Degl=true -Dllvm=true -Dlmsensors=true -Dshared-glapi=true
299
+
300
+# Controllare che la configurazione soddisfi i propri requisiti
301
+meson configure build
302
+# Se si vuole modificare un parametro usare meson configure build -Dparametro=valore
303
+
304
+# Lanciamo la compilazione
305
+ninja -Cbuild
306
+
307
+# Installazione nella cartella prefix configurata precedentemente
308
+sudo ninja -Cbuild install
309
+```
310
+
311
+A questo punto ci serve uno script (che chiamo mesa-master) che ci permetta di
312
+avviare un programma usando Mesa compilato e non quello di sistema:
313
+
314
+```
315
+#!/bin/bash
316
+
317
+#export LIBGL_DEBUG=verbose
318
+#export MESA_DEBUG=1
319
+export LD_LIBRARY_PATH="/opt/mesa-master/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
320
+export LIBGL_DRIVERS_PATH=/opt/mesa-master/lib/x86_64-linux-gnu/dri
321
+export EGL_DRIVERS_PATH=/opt/mesa-master/lib/x86_64-linux-gnu/dri
322
+#export MESA_GLSL_CACHE_DISABLE=1
323
+export MESA_GLSL_CACHE_DIR=~/.cache/mesa-master
324
+#export MESA_GL_VERSION_OVERRIDE=4.2
325
+#export MESA_GLSL_VERSION_OVERRIDE=420
326
+
327
+glxinfo | grep "OpenGL version string"
328
+
329
+"$@"
330
+```
331
+
332
+Potete testare lo script lanciando `mesa-master glxgears`. Dovreste vedere i
333
+famosi ingranaggi che girano.
334
+
335
+![](https://gmg.elinvention.ovh/mgoblin_media/media_entries/187/mesa.png)
336
+
337
+[torvalds]: https://www.phoronix.com/scan.php?page=news_item&px=MTEyMTc
338
+[HSA]: https://en.wikipedia.org/wiki/Heterogeneous_System_Architecture
339
+[DirectFB]: https://en.wikipedia.org/wiki/DirectFB
340
+[DRM]: https://en.wikipedia.org/wiki/Direct_Rendering_Manager
341
+[DRI]: https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure
342
+[Mesa3D]: https://mesa.freedesktop.org/intro.html
343
+[mesamatrix.net]: https://mesamatrix.net/
344
+[EGL]: https://en.wikipedia.org/wiki/EGL_(API)
345
+[amd]: https://en.wikipedia.org/wiki/List_of_AMD_graphics_processing_units
346
+[meson]: https://mesa.freedesktop.org/meson.html