>_ DevTrendsit

Lingua

Home

Linguaggi

Sezioni

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embedded Sicurezza
C

Come quadruplicare la velocità di compressione dei dati senza riscrivere il codice

Perché modificare qualcosa che funziona dagli anni novanta

La libreria zlib originale è apparsa trent'anni fa. Mark Adler e Jean-Loup Gailly hanno creato uno strumento incredibilmente affidabile e portabile. Funziona quasi ovunque, dagli smartwatch ai sistemi operativi legacy. Ma questa universalità ha un rovescio della medaglia.

Per mantenere la compatibilità con compilatori datati e ambienti a 16 bit, il codice zlib deve trascinarsi dietro una serie di workaround. È pieno di controlli sui limiti di memoria e macro per supportare processori arcaici. Per questo motivo, le nuove ottimizzazioni per le istruzioni vettoriali da parte degli sviluppatori moderni non potevano semplicemente essere inserite nel repository principale. Mark Adler mantiene standard elevati di stabilità, e il suo approccio è comprensibile.

È allora che Hans Christian Rosbach (Dead2) ha deciso di compilare le patch della community accumulate in un unico fork. È così che è nato il progetto zlib-ng.

Cosa è cambiato all'interno di zlib-ng

L'idea del fork è semplice: eliminare il codice legacy antico e applicare le istruzioni vettoriali delle CPU moderne. Gli sviluppatori hanno preso le patch da Intel e Cloudflare, rimosso gli esempi degli anni novanta e riscritto gli algoritmi chiave in C11.

I risultati sono stati tangibili. Sull'architettura x86-64, la compressione e la decompressione funzionano circa quattro volte più velocemente rispetto alla zlib standard.

Cosa determina questo guadagno di prestazioni:

  • Istruzioni vettoriali per diverse architetture. AVX2, AVX-512, SSSE3 per x86, NEON per ARM, oltre alle unità vettoriali per POWER, RISC-V, LoongArch e IBM Z vengono utilizzate.
  • Rilevamento automatico delle capacità della CPU a runtime. Il binario compilato sa autonomamente quali funzioni vettorializzate chiamare su uno specifico processore.
  • Algoritmi deflate ottimizzati. Viene utilizzato il lavoro di Intel sull'ottimizzazione della ricerca di ripetizioni, dello shift dell'hash e del calcolo del CRC32.
  • Accesso non allineato sicuro. La lettura e la scrittura della memoria non allineata è ottimizzata insieme a un buffer di bit aggiornato.

Allo stesso tempo, il progetto non cerca di stravolgere il mondo esistente. La libreria può essere compilata con un'API completamente compatibile con la zlib standard, oppure è possibile utilizzare la sua propria API nativa aggiornata.

Come compilare e provarlo da soli

Il progetto ha due sistemi di build: CMake e il buon vecchio configure.

Se usi CMake, la compilazione è familiare:

Il parametro abilita la modalità di compatibilità completa con la zlib classica. L'output è una libreria che può essere sostituita alla di sistema.

Per gli amanti del familiare processo di build non è diverso:

Se usi il gestore di dipendenze vcpkg, non dovrai affatto recuperare manualmente i sorgenti:

Velocizzare le applicazioni con LD_PRELOAD

Uno dei trucchi più interessanti con zlib-ng è velocizzare il software esistente senza modificare il codice. Se il tuo programma esegue il link dinamico con , puoi sostituire la libreria a runtime.

Ecco come lanciare un'utilità con una sostituzione temporanea:

L'applicazione utilizza immediatamente le istruzioni vettoriali del tuo processore senza alcuna modifica al binario.

Tuttavia, gli autori del fork mettono in guardia specificamente nel README: non cercare di sostituire la di sistema a livello di distribuzione nelle directory di Linux. Se qualcosa va storto o emerge una rara incompatibilità, l'intero sistema si bloccherà, inclusi i servizi di sistema. È più sicuro installare il fork in una directory separata come e collegarlo esplicitamente.

Quanto bene è coperto il codice dai test

Il codice responsabile della compressione dei dati deve funzionare senza errori. Perdere anche un singolo bit trasformerà un archivio in spazzatura. Gli autori di zlib-ng hanno preso sul serio i test.

Il repository utilizza un insieme completo di controlli:

  • Sanitizer di memoria e fuzzing tramite OSS-Fuzz.
  • CI nativo ed emulato tramite QEMU per ARM, PowerPC, RISC-V, SPARC64 e S390x.
  • Test unitari basati su Google Test.
  • Misurazioni delle prestazioni utilizzando Google Benchmark.

Grazie al fuzzing continuo, la libreria mantiene un alto livello di affidabilità, critico quando si sostituiscono componenti di sistema core.

Chi trarrà beneficio da zlib-ng

Prima di tutto, il fork sarà utile per i team in cui la compressione e la decompressione dei dati sono diventate un collo di bottiglia. Se stai elaborando gigabyte di log, lavorando con server web come nginx, comprimendo texture nello sviluppo di giochi o elaborando enormi quantità di dati nel backend, zlib-ng fornirà un miglioramento delle prestazioni evidente.

D'altra parte, se il tuo software gira su microcontrollori a 16 bit antichi o sistemi operativi esotici di tre decenni fa, non ha senso toccare la zlib originale collaudata. Il fork è stato creato specificamente per le piattaforme moderne.

Lo strumento sembra maturo ed è mantenuto attivamente dalla community. Se hai bisogno delle massime prestazioni DEFLATE e gzip su hardware moderno, vale la pena dedicare un paio d'ore ed eseguire benchmark sui tuoi dati.

Progetti correlati