Kompression ausführbarer Dateien vs. SquashFS

Silent-Tears

IPPF-Promi
Mitglied seit
3 Aug 2007
Beiträge
7,456
Punkte für Reaktionen
1
Punkte
0
Zuletzt bearbeitet von einem Moderator:
Wie hast Du es komprimiert? Eine compiler option?

EDIT: Ich habe es mit der --enable-compression configure option versucht, scheint aber nicht die compression des binary zu meinen...
Also würde ich gerne wissen wie Du das binary komprimiert hast, und ich meine nicht die komprimierung auf der box durch das fs.
 
Zuletzt bearbeitet:
Laßt bitte die sinnlose Komprimiererei, das spart keinen Speicherplatz im SquashFS und kostet nur wertvolle Zeit für die Dekompression. Siehe meine alten Beiträge zum Thema, z.B. dort und dort. Und auf einem USB-Stick oder einer Festplatte fallen die Dateigrößen sowieso nicht ins Gewicht. Da macht Ihr nur der Box einen Haufen Arbeit beim Rechnen. Sie muß ja dekomprimieren.
 
Laßt bitte die sinnlose Komprimiererei, das spart keinen Speicherplatz im SquashFS und kostet nur wertvolle Zeit für die Dekompression.

Im Squashfs spart es auch nur unwesentlich an Platz, zumindest in neueren Versionen des Squashfs mit lzma. Im JFFS2 allerdings spart es gewaltig an Platz, und dies war mein Testsystem neben dem tmpfs der Box.
Und selbst im Squashfs sollte man noch einmal beweisen, welches die bessere Kompression ist, denn es gibt doch einige Algos, die lzma auf älteren Squashfilesystemen um Längen schlagen.

Und was für einen Nutzen hat es, wenn Du das Binary mit upx komprimiert hast?

Wie oben geschrieben, upx schlägt die Eigenkompressionen des bei mir verwendeten Dateisystems um Längen und komprimiert ein Stück besser als das lzma des Squashfs 2.2x
 
Zuletzt bearbeitet:
Im Squashfs spart es auch nur unwesentlich an Platz, zumindest in neueren Versionen des Squashfs mit lzma.
Bist Du sicher, daß es überhaupt Platz spart? Ich vermute eher, daß es zusätzlichen Platz verbraucht.

Und selbst im Squashfs sollte man noch einmal beweisen, welches die bessere Kompression ist
Das ist doch eine gute Gelegenheit, selbst damit anzufangen. Du hast die Original-Datei, Du hast die mit upx komprimierte Datei, und Du kannst die Datei mit SquashFS komprimieren. Wenn Du dann noch hier das Ergebnis veröffentlichst, haben wir alle etwas davon.

es gibt doch einige Algos, die lzma auf älteren Squashfilesystemen um Längen schlagen.
Hast Du auch Namen und Implementierungen davon? Und was genau heißt "ältere Squashfilesysteme"? Version 2? Version 1?

Wie oben geschrieben, upx schlägt die Eigenkompressionen des bei mir verwendeten Dateisystems um Längen und komprimiert ein Stück besser als das lzma des Squashfs 2.2x
Wenn es ein upx für mipsel gibt, vermute ich mal, daß es auch Quelltexte dafür gibt. Wenn es wirklich besser komprimiert als LZMA und sonst keine gravierenden Nachteile hat, wäre es doch interessant, diese Komprimierung für das gesamte Dateisystem einzusetzen.

Bei mit zum Beispiel kommt mit LZMA folgendes über das gesamte Dateisystem heraus:
Code:
Filesystem size 5762.40 Kbytes (5.63 Mbytes)
        26.45% of uncompressed filesystem size (21782.56 Kbytes)
Inode table size 13068 bytes (12.76 Kbytes)
        23.23% of uncompressed inode table size (56260 bytes)
Directory table size 15168 bytes (14.81 Kbytes)
        49.85% of uncompressed directory table size (30427 bytes)
Das ist über das gesamte Dateisystem immer noch besser als (0,5/1,3) = 38%.
 
Bist Du sicher, daß es überhaupt Platz spart? Ich vermute eher, daß es zusätzlichen Platz verbraucht.
Ja, wenn ich die Kompression erneut komprimiere, dann ist es natürlich so.

Das ist doch eine gute Gelegenheit, selbst damit anzufangen.
Wenn du mir noch sagst, wie man die Kompression einer Datei im Squashfs direkt herausfindet, ausserhalb davon, das Filesystem ständig neu zu flashen und die Gesamtwerte zu vergleichen, dann gern.

Hast Du auch Namen und Implementierungen davon? Und was genau heißt "ältere Squashfilesysteme"? Version 2? Version 1?
Squashfs-Versionen nutzen früher einen etwas anderen lzma-Algo, bzw. noch früher sogar nur gzip-Kompression. Dort konnte upx punkten.

Wenn es wirklich besser komprimiert als LZMA und sonst keine gravierenden Nachteile hat, wäre es doch interessant, diese Komprimierung für das gesamte Dateisystem einzusetzen.
Der Trick bei dem Ding ist, dass man den Algo festlegen kann für das einzelne Executable, es nur executables packt und man somit kein komplettes Filesystem nutzen kann.

Somit ist ein direkter Vergleich zum Verbrauch des kompletten Filesystems nur möglich, wenn man alle binaries mit upx packt, diese im Squashfs-Bereich vor dem packen zu Ersetzen und dann das Ganze auf die Box zu schieben. ISt einfach zu viel Aufwand meines Erachtens nach.

Wie schon einmal erwähnt, lag das von mir gepackte binary auf einer JFFS2-Partition im Flash, die ihres Zeichens dadurch nicht "geplatzt" ist.
 
Ja, wenn ich die Kompression erneut komprimiere, dann ist es natürlich so.
Ich meinte damit, daß der Dekomprimierer vom upx zusätzlichen Platz benötigt. Die bereits komprimierten Daten können vermutlich nicht weiter komprimiert werden und werden daher unverändert übernommen. Ohne den enthaltenen Dekomprimierer wäre der Platzverbrauch gleich, sofern upx besser komprimiert als LZMA.

Wenn du mir noch sagst, wie man die Kompression einer Datei im Squashfs direkt herausfindet, ausserhalb davon, das Filesystem ständig neu zu flashen und die Gesamtwerte zu vergleichen, dann gern.
Es ist nicht notwendig, das Dateisystem zu flashen, um seine Größe zu bestimmen. Es reicht, das Dateisystem zu erstellen.
Im ds-mod wird eine Datei build/modified/filesystem.log erstellt, aus der ich auch die oben genannte Statistik habe.
Wenn Du zwei Dateisysteme erstellst, die als einzigen Unterschied die Datei einmal unverändert und einmal upx komprimiert enthalten, kannst Du feststellen, bei welchem Dateisystem die komprimierte Größe kleiner ist.

Squashfs-Versionen nutzen früher einen etwas anderen lzma-Algo, bzw. noch früher sogar nur gzip-Kompression. Dort konnte upx punkten.
Das Standard SquashFS im Linux Kernel verwendet nur gzip Kompression, die bekanntlich nicht so gut ist. Dies gilt auch noch für das ganz aktuelle SquashFS 3.
Bei den AVM Kernels wird aber zumindest bei den 2.6 Kernels LZMA verwendet. Ob es bei den älteren Firmwares auch schon so war, weiß ich nicht.
Der Trick bei dem Ding ist, dass man den Algo festlegen kann für das einzelne Executable, es nur executables packt und man somit kein komplettes Filesystem nutzen kann.
Ich gehe davon aus, daß der überwiegende Teil der Firmware aus Executables besteht. Außerdem spricht prinzipiell auch nichts dagegen, verschiedene Daten auf verschiedene Arten zu komprimieren, wenn der damit gewonnene Platz den Aufwand rechtfertigt. Insbesondere sollte der gewonnene Platz nicht durch den zusätzlichen Platz für die verschiedenen Dekomprimierer wieder aufgebraucht werden.
 
@OT-Diskussion
Vergesst nicht den RAM-Bedarf. Ist es nicht so, dass upx das komplette Binary irgendwo entpackt ablegt?

Ich weiß, daß der RAM-Bedarf das wichtigste Argument ist, das gegen den Ansatz von upx spricht. Wenn man aber nur eine einzelne Datei in einem unkomprimierten Dateisystem ablegen will, kann ich das auch verstehen. Und mit OT hast Du natürlich recht.

Andererseits wäre es interessant, wenn es tatsächlich eine bessere Kompression gäbe.
 
Ich meinte damit, daß der Dekomprimierer vom upx zusätzlichen Platz benötigt.
Im Endeffekt kommen etwas über 100 Byte pro Datei dazu, wenn ich das richtig verstehe. Mehr Platz wird dann nicht benötigt.
Allerdings ist zum geneaueren studieren des Quelltextes der Heiligabend nicht geeignet ;-)

Wenn Du zwei Dateisysteme erstellst, die als einzigen Unterschied die Datei einmal unverändert und einmal upx komprimiert enthalten, kannst Du feststellen, bei welchem Dateisystem die komprimierte Größe kleiner ist.
Wenn ich jedes noch so kleine binary komprimiere, platzt das Dateisystem aus allen Nähten, der Overhead ist dann zu viel des Guten. Somit sollte man mal Files über einer bestimmten Größe komprimieren, um irgendetwas sinnvolles zu bekommen.

Edit: Der RAM-Bedard ist nicht sonderlich zu beachten, denn:

no memory overhead for your compressed executables because of in-place decompression.

Direkt von der Webseite.


Nähere Tests folgen
 
Es sollte doch relativ einfach sein, mal ein paar unkomprimierte Executables mit UPX und zum Vergleich mit LZMA zu komprimieren, das in AVMs und unseren Firmwares verwendet wird. Über GZIP brauchen wir nicht zu reden, das wird bei uns nicht benutzt. Ich bin nach wie vor der (ungetesteten) Meinung, daß es nichts bringt, UPX zu verwenden, außer in solchen exotischen Spezialfällen wie JFFS, also in unkomprimierten oder schlecht komprimierten Dateisystemen mit enger Größenbegrenzung. Selbst bei NFS-Mounts würde ich sagen, es bringt vermutlich kaum etwas, weil die Binaries auch übers Netzwerk unkomprimiert schnell gezogen sind.
 
Ich hab mir upx mal angeschaut. Da wird ja auch lzma verwendet. Von daher kann die Kompression wohl nicht besser sein wie bei uns...

MfG Oliver

edit:Okay. Die Kompression ist doch besser. Wenn ich die busybox mit upx packe, dann ist das Image um 12kb kleiner.
 
Zuletzt bearbeitet:
Habe es mir auch gerade mal angeschaut und ausprobiert.

Habe eine Binary mit der Größe von 713136 Bytes auf 209368 Bytes komprimiert (upx --lzma --best binary).

FW-Größe:
Mit unkomprimiertem Binary: 5242880 Bytes.
Mit komprimiertem Binary: 5232640 Bytes.

Das sind knapp 10kb Ersparnis. Nicht viel aber immerhin. Leider ist der Programmstart etwas verzögert (klar, muss ja schließlich entpackt werden). Für Programme, die nicht oft neugestartet werden, vielleicht nicht ganz unbrauchbar. Bei der 7050 geht es ja um jedes Byte ;)
 
Aus meiner Sicht ist das für die Katz', wie vermutet.
 
Wahrscheinlich schon. Macht halt nur bei größeren Dateien sinn und es ist auch eine elendige Doppelpackerei. Aber es zeigt auch, dass der Kompressionsalgorithmus hier etwas besser funktioniert.

Was mich bei der Sache interessiert ist, im dsmod wird squashfs v2.2-rc2 verwendet. Kann man auch v3.3 nehmen oder wird das Image dann nicht mehr entpackt? Ließen sich Teile des Algorithmus ändern, ohne das man einen Briefbeschwerer bekommt?
 
Wir verwenden in ds-15.3 SquashFS 3.3 mit LZMA. AVM tut übrigens das Gleiche in der MediaBox und in der 7270-Firmware. Kleiner werden die Firmwares dadurch übrigens nicht, bei Blockgröße 64 KB sogar minimal größer als bei SquashFS 2.x. Größere Blöcke führen zu deutlicher Ersparnis, machen aber auch Probleme im Betrieb, weswegen weder wir noch AVM momentan über 64 KB hinaus gehen. Dennoch packen wir in 15.3 sämtliche FWs, also auch die der anderen Boxen, mit SquashFS 3.3, zumindest bei "replace kernel" (Kernel muß gepatcht werden). Das läuft stabil (ich habe das seit Wochen in W701V und 7170 laufen).
 
Somit bringt das für eine laufende Firmware wohl kaum etwas, denn der Kompressionsalgo stimmt. Die paar KB sind wohl zu berücksichtigen, auch auf 4MB-Boxen. Für Nachladelösungen und ins RAM gecachte Sachen allerdings kann man sich das wohl überlegen, denn dort wird ja sonst auch das ungepackte Binary vorgehalten, und nicht das LZMA-kompirimierte.
Denkbar beim Image wäre bei mir, dass die Kompression von AVM-Seite nicht ganz so gut eingestellt wurde, um die Performance der Box nicht zu beeinträchtigen, aber auch dies spielt für uns hier wohl keine Rolle.
 
Ich hab mir upx mal angeschaut. Da wird ja auch lzma verwendet. Von daher kann die Kompression wohl nicht besser sein wie bei uns...

edit:Okay. Die Kompression ist doch besser. Wenn ich die busybox mit upx packe, dann ist das Image um 12kb kleiner.

Es gibt bei LZMA drei Parameter, mit denen die Kompression beeinflußt werden kann. Beim SquashFS in der Firmware sind es diese Parameter:
Code:
lc = 3
lp = 0
pb = 2
Leider weiß ich nicht, was diese Werte genau bedeuten. Ich vermute aber, daß höhere Werte mehr Aufwand beim Komprimieren und möglicherweise auch mehr Speicherbedarf beim Dekomprimieren bedeuten.

Kann jemand mit upx feststellen, welche Parameter dort verwendet werden? Möglicherweise werden dort auch mehrere Parameter ausprobiert und das beste Ergebnis wird genommen.

Wenn sich herausstellen sollte, daß mit anderen Parametern bessere Ergebnisse kommen, die nicht zuviel Speicher beim Dekomprimieren verbrauchen, könnte man da vielleicht etwas machen.
 
Zu den Parametern (Infos entnommen aus der LZMA-Doku, bei mir zu finden unter /usr/share/doc/lzma, hier in Kopie angehängt):
Code:
Using LZMA encoder/decoder executable 
-------------------------------------- 
(...)
<Switches> 
 
  -a{N}:  set compression mode 0 = fast, 1 = normal 
          default: 1 (normal) 
 
  d{N}:   Sets Dictionary size - [0, 30], default: 23 (8MB) 
          The maximum value for dictionary size is 1 GB = 2^30 bytes. 
          Dictionary size is calculated as DictionarySize = 2^N bytes.  
          For decompressing file compressed by LZMA method with dictionary  
          size D = 2^N you need about D bytes of memory (RAM). 
 
  -fb{N}: set number of fast bytes - [5, 273], default: 128 
          Usually big number gives a little bit better compression ratio  
          and slower compression process. 
 
  -lc{N}: set number of literal context bits - [0, 8], default: 3 
          Sometimes lc=4 gives gain for big files. 
 
  -lp{N}: set number of literal pos bits - [0, 4], default: 0 
          lp switch is intended for periodical data when period is  
          equal 2^N. For example, for 32-bit (4 bytes)  
          periodical data you can use lp=2. Often it's better to set lc0,  
          if you change lp switch. 
 
  -pb{N}: set number of pos bits - [0, 4], default: 2 
          pb switch is intended for periodical data  
          when period is equal 2^N. 
 
  -mf{MF_ID}: set Match Finder. Default: bt4.  
              Algorithms from hc* group doesn't provide good compression  
              ratio, but they often works pretty fast in combination with  
              fast mode (-a0). 
 
              Memory requirements depend from dictionary size  
              (parameter "d" in table below).  
 
               MF_ID     Memory                   Description 
 
                bt2    d *  9.5 + 4MB  Binary Tree with 2 bytes hashing. 
                bt3    d * 11.5 + 4MB  Binary Tree with 3 bytes hashing. 
                bt4    d * 11.5 + 4MB  Binary Tree with 4 bytes hashing. 
                hc4    d *  7.5 + 4MB  Hash Chain with 4 bytes hashing. 
 
  -eos:   write End Of Stream marker. By default LZMA doesn't write  
          eos marker, since LZMA decoder knows uncompressed size  
          stored in .lzma file header. 
 
  -si:    Read data from stdin (it will write End Of Stream marker). 
  -so:    Write data to stdout

Viel Spaß beim Spielen. :D
 

Anhänge

Kostenlos!

Statistik des Forums

Themen
248,917
Beiträge
2,305,038
Mitglieder
378,638
Neuestes Mitglied
Patrick89