LINUX.ORG.RU

Прошу помощи в решении проблемы с распаковкой RAR5 архивов для Linux

 , ,


0

2

Пожалуйста, сообщения, что rar не нужен, оставьте при себе. Этот форум называется Development.

Описание проблемы.

Как известно, сейчас все новые процессоры поддерживают динамическое изменение частоты в зависимости от нагрузки.

Архиватор rar5/unrar5 во время распаковки использует пул из 32 pthread потоков, но, как оказалось, существует проблема с их синхронизацией, и из-за этого распаковка архивов rar5 работает, например, на моём компьютере в шесть раз медленней, чем в Windows.

Во время распаковки в памяти висят 33 потока, которые создают нагрузку не выше 25%, поэтому cpugovernor даже не пытается повысить частоту ядер процессора, т.е. в случае turbo boost под Windows распаковка идёт на частоте ~3.9GHz, под Linux 1.6GHz.

Если вручную выставить cpugovernor в performance, то распаковка ускоряется, но это делает её всё равно медленней в 2,5 раза - т.е. проблема с синхронизацией не уходит, но становится менее выраженной.

Конечно, разбираться в чужом коде - неблагодарное занятие, но если вы хорошо разбираетесь в pthread и C++, то пользователи rar будут вам благодарны.

Для отладки архив rar5 можно создать следующим образом:

rar a -md256m -ma5 -htb -r arc_name.rar files directories

Работу unrar и саму проблему можно отследить командой:

time ./unrar t arc_name.rar

Исходники unrar можно скачать здесь.

Я давно уже не кодер, но, вроде как центр зла здесь:

static inline void CriticalSectionStart(CRITSECT_HANDLE *CritSection)
{
#ifdef _WIN_ALL
  EnterCriticalSection(CritSection);
#elif defined(_UNIX)
  pthread_mutex_lock(CritSection);
#endif
}
ЕМНИП, EnterCriticalSection() оказывается быстрее pthread_mutex_lock(). В целом же, виндовые потоки не соотносятся «1 к 1» с посиксовыми. Портирование кода в лоб приводит к потери производительности. Но пруфов этого не будет.

Я не верю, что патчем в несколько строк можно исправить скорость unrar под Linux, а создавать форк и поддерживать его в актуальном состоянии никто не будет.

mky ★★★★★
()
Ответ на: комментарий от mky

Я общаюсь с Евгением, и, если вы предложите рабочее решение (не обязательно в виде готового патча, но хотя бы идею реализации), то он сделает как надо сам.

Спасибо.

anonymous
()
Ответ на: комментарий от anonymous

Прошу прощения за назойливость, но в 6 или в 2,5 раза быстрее? Из начального поста следует, что разница в 6 раз обусловлена снижением частоты процессора, а сам код при одинаковой частоте процессора медленне 2,5 раза, или не так?

mky ★★★★★
()

Конечно, разбираться в чужом коде - неблагодарное занятие, но если вы хорошо разбираетесь в pthread и C++, то пользователи rar будут вам благодарны.

Всё это, конечно, хорошо, но вопрос уж больно отдаёт «решите мне вот эту задачу». Здесь много очень хороших специалистов, но разбираться в чужом коде и советовать/решать - довольно долгий процесс, и вряд ли кто-то будет делать это бесплатно.

UVV ★★★★★
()

Пожалуйста, сообщения, что rar не нужен, оставьте при себе. Этот форум называется Development.

Описание проблемы. Как известно, сейчас все новые процессоры поддерживают динамическое изменение частоты в зависимости от нагрузки. Архиватор rar5/unrar5 во время распаковки использует пул из 32 pthread потоков, но, как оказалось, существует проблема с их синхронизацией, и из-за этого распаковка архивов rar5 работает, например, на моём компьютере в шесть раз медленней, чем в Windows.

можно я выскажу своё мнение в этом разделе, что многопоточная упаковка данных создаёт больше проблем, чем их решает?

Особенно в том случае, если упаковщик создаёт архив рассчитывая на совершенно иную архитектуру многопоточности?

emulek
()
Ответ на: комментарий от anonymous

Я общаюсь с Евгением, и, если вы предложите рабочее решение (не обязательно в виде готового патча, но хотя бы идею реализации), то он сделает как надо сам.

не сделает. Это принципиально невозможно. Хотя — пробуйте. С интересом ознакомлюсь, если получится. Я — не осилил.

emulek
()
Ответ на: комментарий от anonymous

Попробуйте снизить число потоков, если проблема останется, то вопрос будет уже в другой плоскости (не многопоточности)

nerdogeek
()
Ответ на: комментарий от mashina

а нафига он делает 32 потока? Если на типичной машине не более 4-8 рабочих ядер

ну наверное потому, что 32 практически поровну делится и на 2, и на 4, и на 8 и даже на 6. Причём без каких-то дополнительных мер со стороны Рошала.

emulek
()

readme.txt>

2. Unrar binaries

If you compiled Unrar for OS, which is not present in «Downloads»
and «RAR extras» on http://www.rarlab.com, we will appreciate if you send
us the compiled executable to place it to our site.

Оба-на. Так там рассадник троянов!

anonymous
()
Ответ на: комментарий от mashina

а нафига он делает 32 потока? Если на типичной машине не более 4-8 рабочих ядер

Может оно i/o bound. Другой вопрос почему оно всегда юзает ровно 32 треда

nerdogeek
()
Ответ на: комментарий от mky

ЕМНИП, EnterCriticalSection() оказывается быстрее pthread_mutex_lock()

Через futex работает на линуксах, т.е. тоже со спинлоком вначале.

nerdogeek
()
Ответ на: комментарий от emulek

у наверное потому, что 32 практически поровну делится и на 2, и на 4, и на 8 и даже на 6. Причём без каких-то дополнительных мер со стороны Рошала.

но на 3 уже не делится. И на 6, кстати, тоже. Что делать? Давай другую маразматическую версию

mashina ★★★★★
()
Ответ на: комментарий от emulek

ну наверное потому, что 32 практически поровну делится и на 2, и на 4, и на 8

Прикинь, 8 тоже делится и на 2 и на 4 и на 8... А от деления на 3 и на 6 остаток такой же как у 32-х.

morse ★★★★★
()
Ответ на: комментарий от mashina

32/6 это 4 ядра по 5 потоков и 2 ядра по 6 потоков. Т.е. с т.з. пользователя наблюдающего в htop (диспетчер задач) — практически равномерная нагрузка. Там же всё постоянно прыгает и меняется.

Давай другую маразматическую версию

зачем? Этот архиватор делают для того, что-бы всякое быдло платило за него деньги. Что-бы оно не как xz, «одно ядро грузило». Вот потом-то такой метод написания кода: делаем так, что-бы людям нравилось, а не так, что-бы работало хорошо.

emulek
()
Ответ на: комментарий от morse

А от деления на 3 и на 6 остаток такой же как у 32-х.

не. Ты считаешь абсолютный остаток, а надо относительный. 8%6==32%6==2. Однако 2 это большАя часть 8(25%), но малая часть 32(6.25%). Т.е. остаток по сравнению с 32 примерно в 4 раза меньше.

Да, демагогия и психология, но народ согласен платить за это бабло.

emulek
()
Ответ на: комментарий от anonymous

Я общаюсь с Евгением

Просьба помочь пилить несвободный упаковщик/распаковщик на форуме, посвященном свободной ОС - это сильно.

anonymous
()
Ответ на: комментарий от mashina

для равномерной нагрузки достаточно (n+1) потока

дык тогда код будет сложнее. Проще нафоркать побольше нитей, и пусть ядро само раскладывает. Ещё не понял профита?

А на самом деле, сколько Евгений не форкает, быстрее не будет. Тут всё упирается в память, а память у нас ОДНА. Будет только разве что медленнее там, где Женя это не удосужился протестировать. Что мы и наблюдаем.

emulek
()
Ответ на: комментарий от anonymous

Просьба помочь пилить несвободный упаковщик/распаковщик на форуме, посвященном свободной ОС - это сильно.

ага. Тащем-то этот его долбаный рар никому здесь не нужен. Пусть сам пилит.

А если Женя наконец постиг Дао, то пусть открывает свой упаковщик.

emulek
()
Ответ на: комментарий от nerdogeek

А правда, что в glibc функции thread-safe, со своими отдельными mutex'ами и в коде, напрямую тянутом с винды, это ведёт к двойной работе — сначала явный lock в коде, а потом ещё lock в glibc?

mky ★★★★★
()
Ответ на: комментарий от emulek

Тут всё упирается в память, а память у нас ОДНА.

Я не изучал детально код, но, ведь rar не только пакует/распаковывает, но и хеши или CRC32 считает. С одной памятью разные действия выполняются.

mky ★★★★★
()
Ответ на: комментарий от mky

Без понятия. Утилита strace поможет разъяснить какие syscall были вызваны, т.е. можно посмотреть сколько попыток локов было сделано. valgrind классический профайлер, очень легкий в использовании.

nerdogeek
()
Ответ на: комментарий от mky

Из начального поста следует, что разница в 6 раз обусловлена снижением частоты процессора, а сам код при одинаковой частоте процессора медленнее 2,5 раза, или не так?

Всё верно: при governor:ondemand разница в 6 раз, ибо он не «видит» нагрузку (процессор работает на минимум).

При governor:performance разница в 2,5 раза (процессор работает на максимум).

anonymous
()
Ответ на: комментарий от nerdogeek

Попробуйте снизить число потоков, если проблема останется, то вопрос будет уже в другой плоскости (не многопоточности)

Делал 4 потока (сколько у меня ядер) - это самый быстрый режим распаковки для режима performance. Для ondemand быстрее всего выключение SMP вообще:

Governor: conservative (частота ~ нагрузка)

rar (оригинальный)   - 1m36.580s -
unrar (threads=4)    - 1m10.001s
unrar (threads=3)    - 1m26.487s
unrar (threads=2)    - 1m27.315s
unrar (без DRAR_SMP) - 0m46.156s *

Governor: performance (процессор всегда на максимуме)

rar (оригинальный)   - 0m47.852s
unrar (threads=4)    - 0m34.694s *
unrar (threads=3)    - 0m39.891s
unrar (threads=2)    - 0m55.844s -
unrar (без DRAR_SMP) - 0m45.730s

Что-то совсем неправильно код работает.

anonymous
()
Ответ на: комментарий от nerdogeek

Может оно i/o bound. Другой вопрос почему оно всегда юзает ровно 32 треда

Все тесты я провожу в памяти - диск и дисковое I/O не используется вообще.

anonymous
()
Ответ на: комментарий от emulek

Тут всё упирается в память, а память у нас ОДНА.

Нет, упирается не в память, а в синхронизацию thread'ов.

Иначе бы не было такого idle.

anonymous
()
Ответ на: комментарий от emulek

Женя живёт с RAR'а - вы ему завидуете?

Как предлагаете жить, если он станет open source? Зарядиться работать на чужого дядю?

Или вы знаете примеры программистов одиночек, которые зарабатывают на Open Source проектах? Расскажите - умоляю. Только их нет.

Так что вернёмся к Development.

anonymous
()
Ответ на: комментарий от dikiy

попробуй оставить один поток.

Не катит - смотрите мой ответ выше.

anonymous
()
Ответ на: комментарий от anonymous

вы ему завидуете?

Сперва добейся лол?

anonymous
()
Ответ на: комментарий от nerdogeek

Выше 4 работает как 32, т.е. жутко медленно.

Соберите сами - сборка 3 секунды занимает. Как архив подготовить - я уже написал.

Количество потоков задаётся в unrar/threadpool.hpp

const uint MaxPoolThreads=32;

anonymous
()
Ответ на: комментарий от nerdogeek

Утилита strace поможет разъяснить какие syscall были вызваны, т.е. можно посмотреть сколько попыток локов было сделано.

через strace нельзя, не все try-lock приводят к futex()'ам

mashina ★★★★★
()
Ответ на: комментарий от anonymous

При governor:performance разница в 2,5 раза (процессор работает на максимум).

чтобы, кстати, не посмотреть perf'ом где он тупит?

mashina ★★★★★
()
Ответ на: комментарий от mashina

gperf гонял - ничего не ясно.

Можно прогнать через oprofile, но лень - у меня ядро без него собрано.

anonymous
()
Ответ на: комментарий от mashina

Ага, и даже с performance governor ни один поток не создаёт 100% нагрузки.

Все чего-то ждут.

anonymous
()
Ответ на: комментарий от anonymous

Можно прогнать через oprofile, но лень - у меня ядро без него собрано.

это почти тоже самое, только старее. Я, наверное, не так понял фразу 'процессор работает на максимум', подумал будто грузит всё под максимум. Тогда профайлер ничего интересного не покажет.

mashina ★★★★★
()

Пожалуйста, сообщения, что rar не нужен, оставьте при себе.

Но почему ? Ведь оно, этот рар, действительно самое ненужное «не нужно».

anonymous
()
Ответ на: комментарий от mky

Я не изучал детально код, но, ведь rar не только пакует/распаковывает, но и хеши или CRC32 считает. С одной памятью разные действия выполняются.

основная работа(Over80%) приходится на контекстное моделирование. Остальное уже роли не играет. А контекстное моделирование требует МНОГО памяти со СЛУЧАЙНЫМ доступом. Т.е. её не захешировать.

И да, используемый в раре PPMD симметричный, т.е. жрёт и при распаковке также немеренно, что и при запаковке. Потому юзать его для ядра, которое 1 Линус пакует, а Over9000 народу распаковывает — бред полный.

emulek
()
Ответ на: комментарий от anonymous

Нет, упирается не в память, а в синхронизацию thread'ов. Иначе бы не было такого idle.

ну попробуй в два потока читать МНОГО памяти СЛУЧАЙНО (больше, чем кеш ядра). Два ядра не могут СРАЗУ обратиться к ОДНОЙ памяти, разве это не очевидно? Вот ты idle и видишь, ибо ядра друг друга ждут.

Я пробовал, если делать на одном ядре, то получается чуть быстрее, и в качестве бонуса имеем свободные ядра готовые скажем кино показывать во время распаковки и не тормозить.

А если загрузить все ядра, получается чуть медленнее, ну и вся система колом встаёт. Даже музыку не послушать.

emulek
()
Ответ на: комментарий от anonymous

Женя живёт с RAR'а - вы ему завидуете?

упаси Патрег! Молодец, если и завидую, то по-хорошему.

Как предлагаете жить, если он станет open source? Зарядиться работать на чужого дядю?

А с закрытым кодом он что, на родного дядю работает? Какая разница-то? С хомячков всё равно профита ноль. Они жеж всё равно его рар покрякуют, и будут юзать на халяву. Какая разница? Вот спроси у него, пожалуйста. Меня этот вопрос интересует ещё с 90х годов, когда я его досовскую версию на спор под пиво за вечер сломал. И саму программу, и его «электронную подпись». А я ведь далеко не «суперхакер», а так, рядовой быдлокодер...

Или Женька думает, что кряк не найти? Ну давай найду... (Hint: см. никнейм, там подсказка).

Или вы знаете примеры программистов одиночек, которые зарабатывают на Open Source проектах? Расскажите - умоляю. Только их нет.

есть. Но у нас в рашке (и похоже не только) код принадлежит заказчику, а не программисту. А заказчик не хочет делится. А программист — подчиняется. Вот если-бы я был-бы директором IBM или intel'а, то я-бы делился (а они и делятся). Но...

Так что вернёмся к Development.

я уже говорил: я пробовал, и столкнулся с принципиальными и не решаемыми трудностями. И не только я. Этот наш xz тоже только одно ядро грузит, ибо быстрее. Можно конечно сделать _видимость_ многозадачности, но зачем? Быстрее-то не будет. А вот тупить на распаковке — таки будет (что не удивительно, если все ядра загрузить на 146%). На хрена?

emulek
()
Ответ на: комментарий от nerdogeek

А попробовать 6, 8, 12, 16... потоков? Просто интересно когда он упрется в Амдала.

сам попробуй. У тебя же есть xz? Вот и запусти СРАЗУ два. Этого будет достаточно, если конечно у тебя не двухПРОЦЕССОРНАЯ мать (на которой по памяти на процессор приляпано. НЕ многоядерная!)

emulek
()
Ответ на: комментарий от nerdogeek

Я даже не знаю с чего начать...) Ну, вы подумайте еще раз над комментируемым, а потом посмотрите на ваш ответ.

ну. Посмотрел на тот пост, на который вы отвечаете, подумал... Не очень понятно, что вы хотели сказать своим ответом. Вот этим: Прошу помощи в решении проблемы с распаковкой RAR5 архивов для Linux (комментарий)

emulek
()
Ответ на: комментарий от anonymous

Так что вернёмся к Development.

Developers, Developers, Developers, Developers, Developers, Developers, Developers, Developers, Developers, Developers, Developers, Developers...

Вот вы и возвращайтесь!

quest ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.