Поддержка многопоточности в 7za

Поддержка многопоточности в 7za

(Сначала я разместил это на serverfault, но потом понял, что, вероятно, это относится и к этому месту.)

Я пытаюсь сжать очень большой текстовый файл с помощью 7za (p7zip) 9.20. Параметр -mmt, похоже, не дает никакого эффекта. Я пробовал и -mmt=on, и -mmt=2. Это 8-ядерная машина. Один человек предложил добавить -m0=lzma2 в качестве аргумента, но это просто возвращает мне E_INVALIDARG. Кто-нибудь знает, как это сделать?

Это не имеет никакого эффекта:

7za a -mx=9 -mmt=2 -p myarchive.zip bigfile.txt

И это завершается ошибкой:

7za a -m0=lzma2 -mx=9 -mmt=2 -p myarchive.zip bigfile.txt


7-Zip (A) [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,8 CPUs)
Scanning

Creating archive release_20120601-1-http.zip



System error:
E_INVALIDARG

решение1

В соответствии с-m (Установить метод сжатия) ключ # ZipMultiThread - руководство и документация 7ZIP, mtпо умолчанию используется значение on, поэтому нет необходимости указывать его вообще.

Однако реализация алгоритма DEFLATE в 7zip не поддерживает многопоточность!

Как вы уже обнаружили,

7za a archive.zip bigfile

использует только одно ядро.

Но .zipфайлы сжимают каждый файл по отдельности. При сжатиинесколькофайлов, опция многопоточности сжимает один файл на ядро ​​одновременно.

Попробуйте и вы увидите, что

7za a archive.zip bigfile1 ... bigfileN

будут использоваться все доступные Nядра.

Если вы хотите ускорить сжатиеодинокийфайл, у вас есть два варианта:

  1. Разделить bigfileна части.

  2. Используйте другой алгоритм сжатия.

    Например, реализация алгоритма BZip2 в 7zip поддерживает многопоточность.

    Синтаксис следующий:

    7za a -mm=BZip2 archive.zip bigfile
    

Также синтаксическая ошибка вызвана вашей попыткой использовать алгоритм LZM для .zipконтейнера. Это невозможно.

Возможные алгоритмы для .zipконтейнеров: DEFLATE(64), BZip2 и отсутствие сжатия.

Если вы хотите использовать алгоритм LZM, используйте .7zконтейнер. Этот контейнер также обрабатывает следующие алгоритмы: PPMd, BZip2, DEFLATE, BCJ, BCJ2 и без сжатия.

решение2

Это старый вопрос, и он не является ответом на конкретный вопрос, а лишь отвечает на суть вопроса (Использование всех ядер для сжатия zip-формата)

pigz (параллельный gzip с опцией .zip)

pigz -K -k archive.zip bigfile txt

Это позволит вам получить совместимый с ZIP-файл в 7 раз быстрее при том же уровне сжатия.

Краткое сравнение zip-совместимых и не zip-компрессоров, использующих одно- и многоядерные процессоры.

время на i7-2600k для сжатия 1.0gb txt файла в fedora 20

67s (120mb) 7za (zip,1 thread)
15s (141mb) 7za -mx=4 (zip,1 thread)
17s (132mb) zip (zip,1 thread)
 5s (131mb) pigz -K -k (zip,8 threads)
 9s (106mb) bsc (libbsc.com) (not zip,8 threads)
 5s (130mb) zhuff -c2 (not zip,8 threads)
 2s (149mb) zhuff (not zip,8 threads)

время стены для декомпрессии

4.2s unzip -t
2.0s pigz -t
5.1s bsc d
0.5s zhuff -d

решение3

Другой вариант, чтобы добиться многоголового сжатия в Linux, это использовать то, что использует Facebook,Zстандарт. В Ubuntu установка выполняется так:

sudo apt install zstd

Сверхбыстрое многопоточное сжатие:

tar cf - /folder/you/want/to/compress | zstdmt -o /location/to/output/fileName$(date '+%Y-%m-%d_%H:%M:%S').tar.zst

Вы можете указать уровни сжатия от 1 до 19 (по умолчанию — 3).

Максимальное сжатие (самое медленное):

tar cf - /folder/you/want/to/compress | zstdmt -19 -o /location/to/output/fileName$(date '+%Y-%m-%d_%H:%M:%S').tar.zst

Средняя компрессия (уровень 10):

tar cf - /folder/you/want/to/compress | zstdmt -10 -o /location/to/output/fileName$(date '+%Y-%m-%d_%H:%M:%S').tar.zst

По моему общему опыту, сжатие Zstandard не такое сильное, как 7zip, но оно намного быстрее, и zstdmtкоманда пытается задействовать все ядра.

Кстати, в Windows 7zip использует все процессоры по умолчанию, и я очень разочарован, что в Linux это не так. Это было так в течение нескольких лет, на данный момент, и я хотел бы, чтобы 7zip был многопоточным по умолчанию и в Linux.

решение4

Просто используйте -mmt[N+1]

Например: -mmt2 — для одного потока, -mmt9 — для восьми потоков.

Связанный контент