>_ DevTrendspl

Język

Strona główna

Języki

Sekcje

Frontend Backend Mobilne DevOps AI / ML GameDev Blockchain Systemy wbudowane Bezpieczeństwo
C

Jak przyspieszyć kompresję danych czterokrotnie bez przepisywania kodu

Dlaczego zmieniać coś, co działa od lat dziewięćdziesiątych

Oryginalna biblioteka zlib pojawiła się trzydzieści lat temu. Mark Adler i Jean-Loup Gailly stworzyli niezwykle niezawodne i przenośne narzędzie. Działa prawie wszędzie — od smartwatchy po starsze systemy operacyjne. Ale ta uniwersalność ma swoją cenę.

Aby zachować kompatybilność ze starymi kompilatorami i środowiskami 16-bitowymi, kod zlib musi ciągnąć za sobą mnóstwo obejść. Jest pełen sprawdzania limitów pamięci i makr wspierających archaiczne procesory. Z tego powodu świeże optymalizacje instrukcji wektorowych przez nowoczesnych programistów po prostu nie mogły zostać wprowadzone do głównego repozytorium. Mark Adler utrzymuje wysoką poprzeczkę stabilności, a jego podejście jest zrozumiałe.

Tutaj właśnie Hans Christian Rosbach (Dead2) postanowił skompilować nagromadzone patchy społeczności w jeden fork. Tak właśnie powstał projekt zlib-ng.

Co zmieniło się wewnątrz zlib-ng

Idea forka jest prosta: porzucić starożytny kod dziedziczny i zastosować instrukcje wektorowe nowoczesnych procesorów. Deweloperzy wzięli patche od Intela i Cloudflare, wyczyścili przykłady z lat dziewięćdziesiątych i przepisali kluczowe algorytmy w C11.

Rezultaty były namacalne. Na architekturze x86-64 kompresja i dekompresja działają około czterokrotnie szybciej niż w standardowym zlib.

Co napędza ten wzrost wydajności:

  • Instrukcje wektorowe dla różnych architektur. Wykorzystywane są AVX2, AVX-512, SSSE3 dla x86, NEON dla ARM, a także jednostki wektorowe dla POWER, RISC-V, LoongArch i IBM Z.
  • Automatyczne wykrywanie możliwości procesora w czasie wykonania. Skompilowany plik binarny sam wie, które funkcje zwektoryzowane wywołać na danym procesorze.
  • Szybkie algorytmy deflate. Wykorzystywana jest praca Intela nad optymalizacją wyszukiwania powtórzeń, przesuwania skrótów i obliczania CRC32.
  • Bezpieczny dostęp do pamięci bez wyrównania. Odczytywanie i zapisywanie pamięci bez wyrównania jest zoptymalizowane wraz ze zaktualizowanym buforem bitowym.

Jednocześnie projekt nie próbuje burzyć istniejącego świata. Biblioteka może być budowana z API w pełni kompatybilnym ze standardowym zlib, lub możesz użyć jej własnego zaktualizowanego natywnego API.

Jak zbudować i wypróbować samodzielnie

Projekt ma dwa systemy budowania: CMake i stary dobry configure.

Jeśli używasz CMake, budowanie wygląda znajomo:

Parametr włącza tryb pełnej kompatybilności z klasycznym zlib. Wynikiem jest biblioteka, którą można podstawić pod systemowe .

Dla fanów znajomego procesu budowania nie różni się niczym:

Jeśli używasz menedżera zależności vcpkg, w ogóle nie musisz ręcznie pobierać źródeł:

Przyspieszanie aplikacji za pomocą LD_PRELOAD

Jedną z najciekawszych sztuczek z zlib-ng jest przyspieszanie istniejącego oprogramowania bez zmiany jego kodu. Jeśli twój program łączy się dynamicznie z , możesz podstawić bibliotekę w czasie wykonania.

Oto jak uruchomić narzędzie z tymczasowym podstawieniem:

Aplikacja natychmiast wykorzystuje instrukcje wektorowe twojego procesora bez żadnych zmian w pliku binarnym.

Jednak autorzy forka specjalnie ostrzegają w README: nie próbuj zastępować systemowego na poziomie dystrybucji w katalogach w Linuksie. Jeśli coś pójdzie nie tak lub pojawi się rzadka niezgodność, cały system się zawali, w tym usługi systemowe. Bezpieczniej jest zainstalować fork w osobnym katalogu, takim jak , i połączyć go jawnie.

Jak dobrze kod jest pokryty testami

Kod odpowiedzialny za kompresję danych musi działać bezawaryjnie. Utrata nawet jednego bitu zamieni archiwum w śmieci. Autorzy zlib-ng potraktowali testowanie poważnie.

W repozytorium stosowany jest kompleksowy zestaw sprawdzeń:

  • Sanitizery pamięci i fuzzing przez OSS-Fuzz.
  • Natywne i emulowane CI przez QEMU dla ARM, PowerPC, RISC-V, SPARC64 i S390x.
  • Testy jednostkowe oparte na Google Test.
  • Pomiary wydajności przy użyciu Google Benchmark.

Dzięki ciągłemu fuzzingowi biblioteka utrzymuje wysoki poziom niezawodności, co jest krytyczne przy wymianie podstawowych komponentów systemowych.

Kto skorzysta na zlib-ng

Przede wszystkim fork będzie przydatny dla zespołów, gdzie kompresja i dekompresja danych stały się wąskim gardłem. Jeśli przetwarzasz gigabajty logów, pracujesz z serwerami WWW jak nginx, kompresujesz tekstury w tworzeniu gier lub przetwarzasz ogromne ilości danych w backendzie, zlib-ng zapewni zauważalny wzrost szybkości.

Z drugiej strony, jeśli twoje oprogramowanie działa na starożytnych mikrokontrolerach 16-bitowych lub całkowicie egzotycznych systemach operacyjnych sprzed trzech dekad, nie ma sensu dotykać sprawdzonego oryginalnego zlib. Fork został stworzony konkretnie dla nowoczesnych platform.

Narzędzie wygląda dojrzałe i jest aktywnie rozwijane przez społeczność. Jeśli potrzebujesz maksymalnej wydajności DEFLATE i gzip na nowoczesnym sprzęcie, warto poświęcić parę godzin i uruchomić testy porównawcze na swoich danych.

Powiązane projekty