html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Как я писал LZ4 плагин компрессии для Reiser4 из песочницы

image

Объяснять что такое Reiser4 и с чем его едят я не буду, т. к. на этот счет достаточно информации [1, 2] и повторять её я не вижу смысла. Поэтому начну пожалуй с того, что Reiser4 я решил опробовать в 2010 году, но из-за проблем использования прозрачной компрессии совместно с упаковкой хвостов (как оказалось были проблемы в flush процедуре, которые на данный момент решены[3]) перешел обратно на ReiserFS. В 2013 году я узнал о том, что эта проблема решена [4] и я снова вернулся на Reiser4 (LZO1 на стационарной системе, на ноутбуке без сжатия). Через какое-то время я вспомнил про новости о «Чрезвычайно быстром алгоритме сжатия» LZ4, а так-же о том, что комьюнити Illumos добавило поддержку оного в ZFS. Тут меня посетила мысль: «А было-бы здорово будь в Reiser4 поддержка LZ4»! Вот я и начал «приделывать» его к Reiser4.

Сначала я просмотрел код плагина ccreg40 (как известно Reiser4 имеет плагиновую структуру). Все начинается с файла fs/reiser4/plugin/compress/compress.h в котором есть перечисление reiser4_compression_id:
typedef enum {
	LZO1_COMPRESSION_ID,
	GZIP1_COMPRESSION_ID,
	LAST_COMPRESSION_ID,
} reiser4_compression_id;

В нем обозначаются идентификационные номера того или иного алгоритма сжатия (по умолчанию доступны LZO1 и GZIP1). Последним в списке идет LAST_COMPRESSION_ID, который нужен для определения размеров различных таблиц содержащих информацию о алгоритмах и сопутствующих им функций.

Продолжаем мы в файле fs/reiser4/plugin/compress/compress.c, в котором мы уже непосредственно описываем функции. Всего 7-мь основных функций:
  • init() – Нужна, если алгоритм требует предварительной инициализации чего-либо. Ни GZIP1, ни LZO1, ни LZ4 этого не требуют, поэтому они просто возвращают 0.
  • overrun() – Возвращает максимальный размер «хвоста», который может образоваться при сжатии. К примеру если не учитывать «хвост», то при несжимаемых входящих данных, произойдет выход за пределы выходного буфера. К примеру для GZIP1 это значение составляет 0, для LZO1 “src_len/64+19”, а для LZ4 “src_len/255+16”.
  • alloc() – Выделяет память для нужд алгоритма.
  • free() – Освобождает память, выделенную для нужд алгоритма.
  • min_size_deflate () – Возвращает минимальный размер блока, который все еще имеет смысл сжимать.
  • compress() – Сжимает данные.
  • decompress() – Распаковывает данные.


Подробнее остановлюсь на функциях alloc()/free(). Один из аргументов которые они принимают, значится аргумент act типа tfm_action. tfm_action является перечислением описанным в заголовочном файле fs/reiser4/plugin/compress/compress.h (имеет такую-же структуру как и reiser4_compression_id), в котором два элемента TFMA_READ и TFMA_WRITE.
typedef enum {
	TFMA_READ,   /* decrypt, decompress */
	TFMA_WRITE,  /* encrypt, compress */
	TFMA_LAST
} tfm_action;

Таким образом можно определить момент, вызывания функции, при чтении или при записи. Некоторые алгоритмы требуют дополнительную память для декомпрессии, и таким образом мы правильно выделим нужное количество памяти. К примеру алгоритм GZIP1 требует дополнительной памяти и мы выделяем для него оную, а алгоритмы LZO1/LZ4 не требуют и мы не выделяем её.

Заканчивается все в том-же файле compress.c, описанием массива compression_plugins, в котором мы указываем тип плагина, его идентификационный номер, заголовок, функции и т. д.
	[LZ4_COMPRESSION_ID] = {
		.h = {
			.type_id = REISER4_COMPRESSION_PLUGIN_TYPE,
			.id = LZ4_COMPRESSION_ID,
			.pops = &compression_plugin_ops,
			.label = "lz4",
			.desc = "lz4 compression transform",
			.linkage = {NULL, NULL}
		},
		.init = lz4_init,
		.overrun = lz4_overrun,
		.alloc = lz4_alloc,
		.free = lz4_free,
		.min_size_deflate = lz4_min_size_deflate,
		.checksum = reiser4_adler32,
		.compress = lz4_compress,
		.decompress = lz4_decompress
 	}


Теперь о том, что я изменил в коде LZ4. Для начала я убрал весь код связанный с Microsoft Visual Studio (может когда-нибудь и соберут ядро Linux посредством компилятора MS VS, но явно это будет не в ближайшем будущем) и C++ (один extern “C”). Затем убрал код, связанный с оптимизацией для BigEndian систем, которая делала выходную информацию несовместимой с LittleEndian системами и код, позволяющий использовать стековую память вместо обычной (получится быстрее, но мы в ядре, нам такие вольности не пройдут даром). Напоследок убрал из кода функции malloc()/free(), добавив в список аргументов функций указатель на участок памяти, выделенной для нужд LZ4 (вспомните alloc()).

Ну а теперь самое главное, как все это работало… откровенно говоря, плохо. Плагин LZ4 работал медленнее и сжимал хуже плагина LZO1. Замеры проводились на живой системе, в однопользовательском режиме. В замер входила операция размонтирования раздела (чтоб сработали sync/flush процедуры и файлы полностью записались на диск). Производилось три теста: линейное запись/чтение на диск файла забитого нулями (из /dev/zero), линейное чтение/запись несжимаемого файла (предварительно взятого с /dev/urandom и записанного в память на tmpfs) и распаковка/сжатие исходных кодов ядра Linux версии 3.9.5. Из всех тестов, плагин с LZ4 показал преимущество только при записи/чтении файла с нулями. Во всех остальных тестах, LZO1 обошел LZ4 и по скорости сжатия/декомпрессии, и по конечному объему файлов.

В ходе дальнейших исследований (fullbench из состава LZ4 и lz4c vs lzop), было выяснено, что LZ4 теряет все свои свойства при блоках маленького размера, а проявляет заявленные свойства [5] только на больших блоках, к примеру в fullbench по умолчанию 4MiB, в lz4c 8MiB. Как выразился Эдуард Шишкин: «4MiB — это как-то многовато. LZO1 сжимает куски и много мельче..» [6]

Таким образом я выяснил, что для Reiser4 LZO1 является более предпочтительным вариантом, ежели LZ4. Кстати говоря, что-то мне подсказывает, что поддержка LZ4, которая была добавлена сообществом, в ZFS будет проявлять себя далеко не всегда (хотя по сравнению с LZJB всегда), и безуспешные попытки протолкнуть LZ4 в Linux [7] (в качестве возможности использования для сжатия ядра или initram) тому подтверждение. Что до LZ4 в btrfs… Эдуард Шишкин наглядно рассказал о том, что из себя представляет btrfs [8] и как ведется его разработка.



Патч Reiser4 для Linux 3.9
Патч LZ4 для Reiser4
P.S. Функцию LZ4_decompress_safe() немного переделать нужно, но смысла нет, поэтому я не стал.
Патч для reiser4progs
[1] habrahabr.ru/post/45873/
[2] http://theoks.net/~onekopaka/Reiser4Site/v4.html
[3] marc.info/?l=reiserfs-devel&m=135146138331012&w=2
[4] sourceforge.net/p/reiser4/discussion/general/thread/2bca4f8e/
[5] code.google.com/p/lz4/
[6] sourceforge.net/p/reiser4/discussion/general/thread/780facb4/
[7] lwn.net/Articles/534168/
[8] habrahabr.ru/post/108629/
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

0

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • habrahabr.ru
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции